ruby-on-rails - view教程 - ruby单元测试




在大型Rails应用程序中加速RSpec测试 (8)

我的RSpec测试中有超过2000个示例的Rails应用程序。 不用说,这是一个很大的应用程序,还有很多需要测试的东西。 在这一点上运行这些测试是非常低效的,因为它需要很长时间,所以在推新版本之前,我们几乎处于不鼓励写它们的地步。 我在spec.opts中添加了-profile来查找最长的运行示例,其中至少有10个平均需要10秒才能运行。 RSpec专家是否正常? 一个例子10秒完全太长了吗? 我意识到,有2000个例子,需要花费不小的时间来彻底测试所有的东西 - 但在这一点上4个小时有点可笑。

你看到什么样的时间是你最长时间运行的例子? 我能做些什么来排除现有的规格,以便找出瓶颈并帮助加快速度。 在这一点上,每一分钟都会有帮助。





删除现有的测试套件。 将会非常有效。


对于任何单个测试来说,10秒是非常长的时间。 我的直觉是你的规格目标同时运行单元和集成测试。 这是一个典型的项目,并且在某个阶段,如果你想生产更多,更快的产品,你需要克服这个技术债务 。 有许多策略可以帮助你做到这一点...我会推荐一些我过去使用的策略。

1.从集成测试中分离出单元

我要做的第一件事是将单元与集成测试分开。 您可以通过以下方式执行此操作

  1. 将它们移到(在spec目录下的单独文件夹中) - 并修改耙机目标
  2. 标记它们(rspec允许您标记您的测试)

哲学是,你希望你的常规构建速度很快 - 否则人们不会太乐意经常运行它们。 所以回到那个领域。 让您的常规测试快速运行,并使用持续集成服务器运行更完整的构建。

集成测试是一个涉及外部依赖性的测试(例如数据库,WebService,队列,还有一些会争论FileSystem)。 单元测试只是测试你想要检查的特定代码项目。 它应该运行得很快(在45秒内9000可能),即大部分应该在内存中运行。

2.将集成测试转换为单元测试

如果单元测试的大部分小于集成测试套件,则会出现问题。 这意味着不一致将开始变得更加容易。 所以从这里开始创建更多的单元测试来替代集成测试。 在这个过程中你可以做的事情是:

  1. 使用模拟框架而不是真正的资源。 Rspec有一个内置的模拟框架。
  2. 在单元测试套件上运行rcov。 用它来测试你的单元测试套件的完整程度。

一旦您有适当的单元测试来替换集成测试,请移除集成测试。 重复测试只会使维护变得更糟。

3.不要使用灯具

装置是邪恶的。 改用工厂(机械师或factory_girl)。 这些系统可以构建更多的适应性数据图表,更重要的是,它们可以构建您可以使用的内存对象,而不是从外部数据源加载内容。

4.添加检查以停止单元测试成为集成测试

现在你已经有了更快的测试,有时间进行检查以防止再次发生。

有一些库试图访问数据库(UnitRecord)时会出现猴子补丁活动记录的错误。

你也可以尝试配对和TDD,这可以帮助你的团队编写更快的测试,因为:

  1. 有人在检查 - 所以没有人会懒惰
  2. 正确的TDD需要快速反馈。 缓慢的测试只会让整个事情变得痛苦。

5.使用其他库来克服问题

有人提到spork(加速rails3下测试套件的加载时间),hydra / parallel_tests - 并行运行单元测试(跨多个内核)。

这应该最后使用。 你的真正问题是在步骤1,2,3中完成的。解决这个问题,你将能够更好地发挥其他基础设施的作用。



每个例子10秒似乎是一个很长的时间。 我从来没有见过一秒钟以上的规格,而且大多数时间要少得多。 你在测试网络连接吗? 数据库写入? 文件系统写入?

尽可能多地使用mock和stubs - 它们比编写碰到数据库的代码快得多。 不幸的是,嘲讽和剔除也需要更多时间来编写(并且难以正确执行)。 你必须平衡写测试的时间和运行测试的时间。

我第二次安德鲁格里姆关于调查CI系统的评论,这可能允许你并行化你的测试套件。 对于尺寸大小的东西,这可能是唯一可行的解​​决方案。






bdd