Rails 系统规格是否仍然需要 DatabaseCleaner?

Is DatabaseCleaner still necessary with Rails system specs?

根据我所阅读的有关 Rails 5.1 新系统规范的所有内容,我的理解是 Rails 现在可以在内部处理数据库事务。

来自 Rspec's blog:“[以前] 您的测试和被测代码不能共享数据库事务,因此您不能使用 RSpec 的内置机制来回滚数据库更改,而不是需要 gem 之类的数据库清理器。通过系统测试,Rails 团队已完成艰苦的工作以确保情况并非如此,因此您可以安全地使用 RSpec 的机制,不需要额外的 gem."

我的经历不同:

  1. 我的 Rspec 功能测试在升级到 Rails 后全部通过 5.1.
  2. 我将 'feature' 规格重命名为 'system' 规格。所有测试都通过了。
  3. 我删除了 Database Cleaner gem,并删除了 rails_helper.rb 中的所有引用。 JS 测试现在由于 validates uniqueness 错误而失败。非 JS 测试通过。

我的测试很简单。

let(:subject) { page }
let(:user) { create :user, name: "TestUser" }
it "displays the user page", :js do
  visit user_path(user)
  it is_expected.to have_content "TestUser"
end

禁用数据库清理器并 :js => true 我得到 user named TestUser already exists。使用 :js => false 测试通过。

系统测试和rspec的当前情况如何? Rails 是在内部处理数据库事务,还是仍然需要数据库清理器?有没有人遇到过这个,或者可以指出相关信息?

您不需要 DatabaseCleaner gem。以下是您需要执行的步骤的快速摘要:

  1. 删除 capybara-selenium gem 和 database_cleaner gem
  2. 添加selenium-webdrivergem
  3. 确保您使用的是 Rails 5.1.5 或更高版本。 Rails 5.1 的早期版本在 ActionDispatch::SystemTesting::Server 中有一个缺陷导致了问题(已修复 here)。
  4. 在您的 rails_helper 文件中,设置 config.use_transactional_fixtures = true
  5. 如果您使用 Devise 进行身份验证,请在您的 rails_helper 文件中设置 config.include Devise::Test::IntegrationHelpers, type: :system
  6. 根据 Noel Rappin 的 post 设置一个 basic_configure 文件。
  7. RSpec.feature 全部替换为 RSpec.describe

有关我如何管理切换的更多详细信息,请参阅 this commit。这很麻烦,但希望现在 5.1.5 已经解决了 ActionDispatch::SystemTesting::Server 问题(我不得不在 5.1.4 中修补文件,但你现在不必这样做)。