8

我有一个 Capybara 的功能规范作为登录页面,我正在使用 FactoryGirl + DatabaseCleaner

require 'rails_helper'

feature 'Admin signs in' do

  background do
    FactoryGirl.create(:user)
  end

  scenario 'with valid credentials' do
    visit admin_root_path
    fill_in 'user_email', :with => 'email@email.com'
    fill_in 'user_password', :with => 'testpassword'
    click_button 'Sign in'
    expect(page).to have_content('Dashboard')
  end

  scenario 'with invalid credentials' do
    visit admin_root_path
    fill_in 'user_email', :with => 'email@email.com'
    fill_in 'user_password', :with => 'wrongpassword'
    click_button 'Sign in'
    expect(page).to have_content('Admin Login')
  end

end

运行测试,我收到以下错误:

1) Admin signs in test with invalid credentials
 Failure/Error: FactoryGirl.create(:user)
 ActiveRecord::RecordInvalid:
   Validation failed: Email has already been taken

我认为 DatabaseCleaner 会恢复更改,但看起来用户记录在数据库中持续存在直到第二个场景块。

如何确保在第一个场景之后清理数据库?

我在这篇文章之后配置了数据库清理器

# support/database_cleaner_spec.rb

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end

我还更新了规范帮助文件:

config.use_transactional_fixtures = false
4

5 回答 5

10

我错误地假设spec/support文件夹中的配置文件是自动加载的,但事实证明我不得不取消注释spec/rails_helper.rb中的以下行

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

DatabaseCleaner 配置文件是正确的,只是根本没有加载。

于 2015-04-06T16:58:56.127 回答
8

确保您在 spec/rails_helper.rb 中有以下配置

RSpec.configure do |config|
 config.use_transactional_fixtures = true
end

这个想法是从一个干净的数据库开始每个示例,创建该示例所需的任何数据,然后通过在示例结束时简单地回滚事务来删除该数据。

于 2015-04-06T08:16:58.847 回答
0

使用这些设置:

config.before(:suite) do
  DatabaseCleaner.clean_with(:truncation)
end
于 2015-04-06T07:49:06.487 回答
0

如果您在测试中的某个方法中使用 MySQL 并更改表(重置自动增量或任何 DDL 操作),则事务策略将失败并且您的数据库将不会被清理。

为了修复,您必须像这样声明一个配置块:

config.before(:each, :altering_database => true) do
  DatabaseCleaner.strategy = :truncation
end

并将此配置添加到您的测试上下文中:

context "when you alter the DB", :altering_database => true do...

注意:这会减慢您的测试速度,因此请注意不要滥用它。

于 2016-10-13T15:34:13.937 回答
0
  config.before(:example) do
    DatabaseCleaner.clean_with(:truncation)
  end

为我工作!

于 2017-07-05T13:29:01.887 回答