单个测试运行10秒钟非常长。我的直觉是你的规格目标在同时运行单元测试和整合测试。这是项目通常会遇到的问题,如果想要更多更快地生产,你需要克服这种技术债务。有许多策略可以帮助你做到这一点...我将推荐一些我过去使用过的方法。
1. 将单元测试和整合测试分离
首先,我会将单元测试和整合测试分开。你可以通过以下两种方式之一来完成:
- 移动它们(到spec目录下的不同文件夹中)- 并修改rake目标
- 给它们打标签(rspec允许你为测试打标签)
这种哲学认为,你希望正常的构建速度很快 - 否则人们就不会很高兴经常运行它们。因此回到那个领域。让你的常规测试运行快速,并使用持续集成服务器来运行更完整的构建。
整合测试是涉及外部依赖关系的测试(例如数据库、Web服务、队列,某些人可能会争论FileSystem)。单元测试只测试你想要检查的特定代码项。它应该快速运行(45秒内的9000次测试是可能的),即大部分都应该在内存中运行。
2. 将整合测试转换为单元测试
如果你的单元测试数量比整合测试套件还少,那么你就有问题了。这意味着不一致性将更容易出现。因此,从这里开始,创建更多的单元测试来替换整合测试。以下是有助于这个过程的一些事情:
- 使用模拟框架而不是真实资源。Rspec有一个内置的模拟框架。
- 在你的单元测试套件上运行rcov。使用它来衡量你的单元测试套件的彻底程度。
一旦你有了适当的单元测试来替换整合测试 - 删除整合测试。重复测试只会使维护变得更糟。
3. 不要使用夹具
固定数据是有害的。使用工厂代替(machinist或factorybot)。这些系统可以构建更具适应性的数据图,更重要的是,它们可以构建内存中的对象,您可以使用这些对象,而不必从外部数据源加载数据。
4. 添加检查以防止单元测试变成集成测试
现在您已经实现了更快速的测试,是时候添加检查以防止再次发生这种情况了。
有些库可以monkey patch ActiveRecord以在尝试访问数据库时抛出错误(UnitRecord)。
您还可以尝试配对编程和TDD,因为这可以帮助强制您的团队编写更快速的测试,原因如下:
- 有人在检查-所以没有人会变懒
- 正确的TDD需要快速反馈。缓慢的测试只会使整个过程痛苦不堪。
5. 使用其他库来解决问题
有人提到spork(加速rails3测试套件的加载时间),hydra/parallel_tests-以并行方式运行单元测试(跨多个内核)。
这应该是最后使用的。您真正的问题在步骤1、2、3中。解决这个问题后,您将能够更好地部署其他基础设施。
perftools.rb
与您的测试框架一起,了解哪些部分占用了大部分时间。取出前10个调用并尝试消除/简化它们。然后重复此过程,直到满意为止。 - aledalgrande