为什么Mocha测试用例应该是无状态的? [英] Why should Mocha test cases be stateless?

查看:81
本文介绍了为什么Mocha测试用例应该是无状态的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常的建议是, Mocha测试用例不应共享状态.鉴于Mochas严格执行测试用例的顺序性质,我真的不理解这种建议.还有更多-我认为这很可疑.

It is a common recommendation, that Mocha test cases should not share state. In light of Mochas strongly sequential nature of execution of test cases, I really do not understand this recommentation. And more - I see it dubious.

如果严格地一个接一个地执行测试用例(甚至是异步用例),则不会存在时间争用问题或其他无法预测的执行顺序的风险.

If the test cases, even asynchronic ones, are executed strictly one after another, there is no risk of time-race problems or other unpredicted execution sequence.

让我们采用这种摩卡结构:

Let's take this Mocha structure:

describe
   describe
     it1
     it2    // async
     it3
   describe
     it4
     it5
describe
   describe
     it6    // async
     it7    // async
     it8
   describe
     it9
     it10

测试用例将始终按照明确的顺序执行,即it1,it2,... it10,无论它们是同步还是异步,甚至在描述的层次结构上也独立.以下结构将产生完全相同的输出:

Test cases will ALWAYS be executed in clear sequential order, it1, it2,... it10, independently on whether they are sync or async, independently even on hierarchy of describes. The following structure will produce perfectly the same output:

describe
   it1
   it2    // async
   it3
   it4
   it5
   it6    // async
   it7    // async
   it8
   it9
   it10

在单个describe()中的测试用例之间共享数据可以使测试用例之间的通信变得更加轻松自如,

Shared data between test cases in a single describe() can make it much easier and comfortable to communicate between test cases in order to:

  • 重用测试代码,并避免在每个代码中重复相同的逻辑(或 其中一些)测试用例.钩子在这里可以很方便,但有时是 预期比他们提供的控制更多
  • 减少测试执行时间-可以节省大量时间,避免过多的钩子,这些钩子除了满足有关无状态性的建议外,什么也不做.
  • reuse testing code and avoid repeating the same logic in each (or some of them) test case. Hooks can be handy here, but sometimes is more control expected than they offer
  • to reduce the testing execution time - a lots of time can be saved avoiding too many hooks that do nothing but satisfying this recommendation about statelessness.

另一个有利于在测试用例之间使用共享数据的事实是Mocha代码的这种简单而美观的结构.不同级别的describe()允许对此最终共享数据进行简单明了的范围管理.

Another fact in favor of using shared data between test cases is this simple and nice structure of the Mocha code. Different level of describe()s permit an easy and clear scope management for this eventual shared data.

我看到的唯一不利方面是,当全局变量"被滥用"时,使代码更难于理解,遵循和维护.无论如何,严格的编码是无法避免的.

The only negative side I see is making the code harder to understand, follow and maintain, when the "globals" are being "abused". Anyhow, nothing that cannot be avoided by disciplined coding.

这里有我不知道的东西吗?

Is there something I'm not aware of here?

推荐答案

使用Mocha运行非无状态且相互依赖的测试是可能的.这不是Mocha是设计的目的.归根结底,如果您想在测试之间施加依赖关系,那么可以肯定.但是它带有一些警告.

It is possible to use Mocha to run tests that are not stateless and thus depend on one another. It's just not what Mocha was designed for. At the end of the day, if you want to impose dependencies between your tests, well, sure, you can. It comes with some caveats though.

您引用了在测试之间共享状态的优点:

You cite this advantage to sharing state among tests:

减少测试执行时间

to reduce the testing execution time

好的. 在其他所有条件相同的情况下,我们宁愿拥有一个运行时间更少的测试套件.在运行整个套件时,不重置测试之间的状态可以节省大型测试套件上相当多的时间.但是,事实是所有其他"都不相等:

Sure. All else being equal, we'd rather have a test suite that takes less time to run. Not resetting state between tests could amount to quite a bit of time saved on large test suites when running the entire suite. However, the fact is that "all else" is not equal:

  • 运行整个套件应通过自动过程来完成,该过程将报告已通过和失败的内容.换句话说,应该没有人坐在那里等待整个套件的完成.

  • Running an entire suite should be done by an automated process that reports what passed and what failed. In other words, there should be no one sitting there waiting for the whole suite to complete.

当出现故障或正在实施新测试时,开发人员将只想运行失败的测试或新测试,而不是整个套件.如果套件设计为必须在运行测试N之前运行测试1至N-1,则这将使开发人员等待更多的时间来获得他真正关心的测试结果.这样他就可以坐在那里,以每分钟$ X的速度旋转他的拇指. 多任务"不是答案,因为已经证明切换任务存在认知成本. (确定测试已完成...等等,又是什么问题?")

When there is a failure or when a new test is being implemented, the developer will want to run only that test which fails or the new test, not the whole suite. If the suite is designed so that tests 1 to N-1 must be run before test N is run, then this is that much more time the developer is waiting to get the result of the test he actually cares about. So he can sit there and twiddle his thumbs at a rate of $X/minute. "Multitask" is not the answer, as it has been proved that there is a cognitive cost to switching tasks. ("Ok the test is done... wait, what was the issue again?")

您可以使用--grep选择特定的测试.在大型测试套件中,这极其有用,可避免浪费时间运行您不关心的测试.因此,假设您的测试标题为it1,... it10,而您使用的是--grep it7.由于Mocha使所有测试相互独立,因此它将仅运行适用于it7的任何beforebeforeEach钩子并运行测试(然后运行适用的任何afterafterEach钩子对此).在运行it7之前,它将不会运行it1it6.为了运行这些测试,您必须制作一个--grep来涵盖所有必要的测试,当然,可能总是可以做,但并不令人愉快.

You can use --grep to select specific tests. This is extremely useful on large test suites to avoid wasting time to run tests you do not care about. So let's suppose that the titles of your tests are it1, ... it10 and you use --grep it7. Since Mocha takes all the tests to be independent from one another, it will just run whatever before and beforeEach hooks are applicable to it7 and run the test (and then run whatever after and afterEach hooks apply to it). It won't run it1 to it6 before running it7. For it to run these tests, you'd have to craft a --grep that covers all the necessary tests, which is certainly always possible to do but not pleasant.

在浏览器中运行Mocha时获得的HTML界面中,如果希望Mocha仅运行该测试,则可以单击一个测试.同样,如果您要修复单个失败的测试,这将非常有用.如果发生失败的测试依赖于应该在其之前运行的一堆测试的情况,那么根本就没有等效于这种简单的点击的方法.

In the HTML interface that you get when running Mocha in a browser, you can click on a test if you want Mocha to just run that test. Again, this is extremely useful if you have a single failing test that you want to fix. There's simply no equivalent to this simple click if it happens that the failing test is dependent on a bunch of tests that should run before it.

通常,如果您的测试必须以特定的顺序运行,则必须小心以确保要按测试运行所必需的顺序加载在多个文件中分割的测试.

In general, if your tests must run in a specific order, you have to be careful to ensure that tests split among multiple files are going to load in the order necessary for your tests to run.

例如,使用全局结构在存储在不同文件中的测试之间共享状态是有可能的.但是,当测试位于不同文件中(其中一个文件不是 require时),Mocha处理文件的顺序完全取决于文件系统列出文件的顺序.读取包含它们的目录时的文件.对于那些希望根据词典顺序进行可预测顺序的人来说,有一个--sort选项.如果要施加自己的任意顺序,那么我想您必须将文件命名为01foo.js02bar.js等.

For instance, it would be possible to share state among tests stored in different files using a global structure. However, when tests are in different files (where one file does not require the other), the order in which the files are processed by Mocha is completely dependent on the order in which the filesystem lists the files when the directory that contains them is read. There is a --sort option for those who want a predictable order based on a lexicographic sort. If you want to impose your own arbitrary order, then I guess you'll have to name your files 01foo.js, 02bar.js, etc.

无论是使用Node.js运行Mocha还是在浏览器中运行Mocha,这都是正确的.我有使用RequireJS加载测试文件的套件.请求模块A,B,C不能保证它们将按A,B,C的顺序加载,除非声明C依赖于B(并且可能是A)并且B依赖于A.

This is true whether using Node.js to run Mocha or running Mocha in a browser. I have suites where the test files are loaded with RequireJS. Requesting modules A, B, C won't guaranteed that they'll be loaded in the order A, B, C unless C is declared to depend on B (and maybe A) and B to depend on A.

这篇关于为什么Mocha测试用例应该是无状态的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆