为什么摩卡测试案例应该是无国籍的?

时间:2015-04-08 07:25:59

标签: testing mocha

这是一个常见的建议, Mocha测试用例不应该共享状态。鉴于Mochas强烈顺序执行测试用例的性质,我真的不明白这个推荐。还有更多 - 我觉得这很可疑。

如果测试用例,即使是异步测试用例,也是一个接一个地严格执行,则不存在时间争用问题或其他不可预测的执行顺序的风险。

让我们采用这个Mocha结构:

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

测试用例总是按照清晰的顺序执行,it1,it2,... it10,独立于是同步还是异步,即使在描述的层次结构上也是如此。以下结构将产生完全相同的输出:

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

单个describe()中的测试用例之间的共享数据可以使测试用例之间的通信更加轻松和舒适,以便:

  • 重用测试代码,避免在每个代码中重复相同的逻辑 其中一些)测试用例。钩子在这里很方便,但有时候也是 预期会比他们提供的更多控制
  • 减少测试执行时间 - 可以节省大量时间,避免过多的钩子,除了满足关于无状态的建议之外什么都不做。

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

我看到的唯一消极方面是让代码更难理解,遵循和维护,当"全局"被滥用"。无论如何,没有任何纪律编码无法避免的事情。

我有什么不知道的吗?

1 个答案:

答案 0 :(得分:4)

可能使用Mocha来运行非无状态的测试,从而相互依赖。这不是Mocha为设计的。在一天结束时,如果您想在测试之间强加依赖关系,那么,当然,您可以。但它有一些警告。

针对错误的事情进行优化

你引用这个优势来分享测试中的状态:

  

减少测试执行时间

不确定。 其他条件相同,我们宁愿拥有一个运行时间更短的测试套件。在运行整个套件时,在测试之间不重置状态可能相当于在大型测试套件上节省了相当多的时间。然而,事实是“所有其他”并不相同:

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

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

测试选择

您可以使用--grep选择特定测试。这对于大型测试套件来说非常有用,以避免浪费时间来运行您不关心的测试。因此,我们假设您的测试标题为it1,... it10,并且您使用--grep it7。由于Mocha使所有测试彼此独立,因此它将运行适用于before的任何beforeEachit7挂钩并运行测试(然后运行任何{{1 }和after挂钩适用于它)。在运行afterEach之前,它不会it1运行到it6。要运行这些测试,你必须制作一个涵盖所有必要测试的it7,这当然总是可能做但不愉快。

在浏览器中运行Mocha时获得的HTML界面中,如果您希望Mocha只运行该测试,则可以单击测试。同样,如果您要修复一个失败的测试,这非常有用。如果发生失败的测试依赖于应该在它之前运行的一堆测试,那么就没有相当于这个简单的点击。

测试订单

通常,如果您的测试必须按特定顺序运行,则必须小心确保在多个文件之间拆分的测试将按测试运行所需的顺序加载。

例如,可能使用全局结构在存储在不同文件中的测试之间共享状态。但是,当测试在不同的文件中时(其中一个文件 --grep另一个文件),Mocha处理文件的顺序完全取决于文件系统的顺序在读取包含它们的目录时列出文件。对于那些想要基于词典排序的可预测订单的人,有一个require选项。如果您想强制执行自己的任意订单,那么我猜您必须为文件--sort01foo.js等命名。

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