我有一个Rails应用程序,在我的RSpec测试中有2000多个示例.不用说,这是一个大型应用程序,有很多需要测试.此时运行这些测试是非常低效的,因为它需要很长时间,我们几乎不愿意在推进新构建之前编写它们.我在spec.opts中添加了--profile来查找运行时间最长的示例,其中至少有10个示例平均运行10秒.这在你们RSpec专家中正常吗?对于一个例子来说,10秒是否太长了?我意识到,有2000个例子,要彻底测试所有东西需要花费大量的时间——但在这一点上,4个小时有点可笑.

你看到的最长的例子是什么时候?我可以做些什么来解决现有规范的问题,以找出瓶颈并帮助加快速度.在这一点上,每一分钟都会很有帮助.

推荐答案

10秒对于任何单个测试来说都是很长的时间.我的直觉是,您的规范目标同时运行单元测试和集成测试.这是一个典型的项目,在某个阶段,如果你想生产更多、更快的产品,你需要付出will need to overcome this technical debt美元.有很多策略可以帮助你做到这一点...我会推荐一些我过go 用过的.

1. Separate Unit From Integration Tests

我要做的第一件事是将单元测试与集成测试分开.您可以通过以下方式实现:

  1. 移动它们(到spec目录下的单独文件夹中)——并修改rake目标
  2. 标记它们(rspec允许您标记测试)

我们的理念是,你希望你的常规构建速度更快——否则人们不会太乐意经常运行它们.所以回到那片区域.让常规测试快速运行,并使用持续集成服务器运行更完整的构建.

集成测试是一种涉及外部依赖关系的测试(例如数据库、Web服务、队列,以及一些可能会争论的文件系统).单元测试只是测试您想要判断的特定代码项.它应该运行得很快(可以在45秒内运行9000次),也就是说,它的大部分应该在内存中运行.

2. Convert Integration Tests To Unit Tests

如果单元测试的规模小于集成测试套件,那么就有问题了.这意味着矛盾将开始更容易出现.因此,从这里开始,创建更多的单元测试来取代集成测试.在此过程中,您可以做以下几件事来帮助您:

  1. 使用模拟框架,而不是真正的资源.Rspec有一个内置的模拟框架.
  2. 在单元测试套件上运行rcov.用它来衡量你的单元测试套件有多彻底.

一旦有了合适的单元测试来替换集成测试,请删除集成测试.重复测试只会让维护变得更糟.

3. Don't Use Fixtures

这是邪恶的.改用工厂(机械师或工厂机器人).这些系统可以构建适应性更强的数据图,更重要的是,它们可以构建内存中的对象,而不是从外部数据源加载数据.

4. Add Checks To Stop Unit Tests Becoming Integration Tests

现在,您已经有了更快的测试,是时候进行判断以防止这种情况再次发生了.

有些库在试图访问数据库(UnitRecord)时,会使用monkey patch active record抛出错误.

您还可以try 配对和TDD,这可以帮助您的团队编写更快的测试,因为:

  1. 有人在判断,所以没人偷懒
  2. 正确的TDD需要快速反馈.缓慢的测试只会让整个过程变得痛苦.

5. Use Other Libraries To Overcome The Problem

有人提到spork(加快rails3下测试套件的加载时间)、hydra/parallel_测试——并行运行单元测试(跨多个内核).

这可能是最后一次使用.你真正的问题在于第一、二、三步.解决了这个问题,你就可以更好地利用额外的基础设施.

Ruby-on-rails相关问答推荐

Rails HotWire和View Components:涡轮框架不会取代内容

使用turbo流的部分渲染在rails 7中不起作用.

本地主机的上衣配置

为什么这个rails Collection_select不呈现关联属性?

ArgumentError 用于 Ruby on Rails 中非常简单的初始化方法,没有参数

Rails 3 - Select 包含?

如何在我的 rails 应用程序中测试 ActiveRecord::RecordNotFound?

判断 DateTime 值是今天、明天还是以后

在 Windows 上使用 Ruby 进行开发

模型验证中的 Rails 国际化 (I18n):可能与否?

RSpec > 有没有办法用一个命令运行所有测试?

rails 4.0, rake db:sessions:create

带有 master.key 的 Rails 5.2 - Heroku 部署

Rails 3.0 中的 f.error_messages

如何对这个哈希数组进行分组?

加载常量时自动加载常量时检测到循环依赖

禁用 JS/Ajax 请求时的 ActionController::InvalidAuthenticityToken

如何跳过失败的迁移? (耙分贝:迁移)

ActiveRecord 中多列的索引

Rails 3 设计,current_user 在模型中不可访问?