Rails 3.0.7 - >如何让测试运行得更快?

Fir*_*lem 15 ruby testing performance ruby-on-rails

我正在运行mysql,database_cleaner,Rspec等.到目前为止,我有大约518个测试,它们需要88秒才能运行.这对我来说是不可接受的,因为我的应用程序开发刚刚开始.

因此,在进一步研究之前,我想尝试找到减少运行这些测试所需时间的方法 - 希望无需实际更改测试.

在大多数情况下,我试图使用存根.但是,当我测试模型和查询时,我确实使用了数据库.

我认为database_cleaner正在减慢它们的速度,但我不知道如何在没有它的情况下测试查询和内容.

使用带有":memory:"选项的sqlite3似乎只能减少大约10秒钟(令人失望的结果......)

我能做些什么才能真正加快测试速度?

Rya*_*ner 17

您可以使用各种策略来加快测试时间.如果你刚开始,并且你看到88秒的运行时间,我会想到很多这些适用于你:

  • 使用spork - Spork将执行所有引导和环境需要一次,将其保留在内存中,并且只重新加载测试.它可以帮助您快速运行测试.
  • 对你的测试方式要聪明 - 就我个人而言,我的工作流程是开发测试,运行完整的测试套件以查看失败的内容,然后只运行新的/失败的测试,直到我可以获得绿色.最后,当我完成所有操作后,我最后一次运行套件,看看我是否退回了其他东西.
  • 清理你的Gemfile - 大多数Rails启动时间花费在需求上,如果你有宝石,你就不再使用了,你就是在没有任何好处的情况下增加加载时间.取出你不使用的任何东西,并考虑将只在一个或两个位置使用的东西放在一个命名组中,这样你就可以在执行期间手动要求它们(小心这一点 - 你正在交换初始加载速度以满足请求性能,非常适合开发,但对于制作很糟糕)
  • 要知道什么是存根和模拟 - 例如,如果你真的在进行单元测试,你应该避免触及数据库,或者至少是你的控制器测试.想想班上的责任究竟是什么.控制器不负责保存记录,它负责告诉模型保存记录.即使是模型也不负责保存数据库中的内容,他们负责告诉ActiveRecord.
  • 如果你把事情搞得一团糟,可以考虑不要包括Rails.您需要在测试中删除几乎所有ActiveRecord功能,但如果您能够这样做,您将看到测试时间大幅减少(可能超过一个数量级).


Fir*_*lem 5

瑞安布鲁纳提出了很多很好的建议.他说的一切都是正确的,但不适用于我.

我没有提到工厂女孩,因为我没想到提到它(不要问).事实证明这是非常相关的细节,因为它负责测试运行如此缓慢.

通过简单地从我的控制器测试(我正在使用Factory.build)中删除Factory girl ,我已经设法将它们从50秒降低到类似5.

原因是Factory.build调用Factory.create关联会导致数据库命中...所以如果你有很多关联,那么创建一个新的模型对象需要一段时间.但更重要的是,在我的案例中,这仅占开销的30-35%.Factory_girl实际上花费了65-70%的时间来做非数据库的事情.我不明白为什么,但在强迫每次调用之后Factory.build,构建我的对象仍需要很长时间.基本走向MyClass.new结束了MUCH更快.

我的整个测试套件现在需要不到30秒而不是90秒.通过进行这些改变,这通常会增加300%的速度......但是当谈到控制器测试时,我的速度提高了2000% - 而且我已经踩到了!所有这些性能开销都是由于Factory.build!这就是大部分收益来自的地方.

当然,我回到我的模型中并使用Factory.build或只是MyClass.new在任何地方.

我还添加了:default_strategy => :buildfactories.rb太每当我所能,以防止工厂女孩击中数据库.如果你问我,这应该是默认值,因为这次更改只有1次测试失败了,但是我通过这个改变设法从模型测试中获得了10秒.

如果您遇到类似我的问题,请按照以下步骤操作,您应该注意到2-3倍的速度提升并没有太大的缺点.