Rspec - 如何在每次测试后清理数据库
Rspec - How to clean the database after each test
我有一个用于登录页面的 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 会还原更改,但看起来用户记录会一直保留在数据库中,直到第二个场景块。
如何确保在第一个场景之后清理数据库?
我按照这个 post
配置了数据库清理器
# 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
使用这些设置:
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
确保在 spec/rails_helper.rb
中有以下配置
RSpec.configure do |config|
config.use_transactional_fixtures = true
end
我们的想法是从一个干净的数据库开始每个示例,创建该示例所需的任何数据,然后通过在示例结束时简单地回滚事务来删除该数据。
我错误地假设 spec/support 文件夹中的配置文件是自动加载的,但事实证明我不得不取消注释 spec/rails_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
DatabaseCleaner 配置文件是正确的,只是根本没有加载。
如果您在测试的方法中使用 MySQL 和更改表(重置自动增量或任何 DDL 操作),事务策略 will fail 和您的数据库将不会清洁。
为了修复,您必须像这样声明一个配置块:
config.before(:each, :altering_database => true) do
DatabaseCleaner.strategy = :truncation
end
并将此配置添加到您的测试上下文中:
context "when you alter the DB", :altering_database => true do...
注意:这会减慢您的测试速度,因此请注意不要滥用它。
config.before(:example) do
DatabaseCleaner.clean_with(:truncation)
end
对我有用!
我有一个用于登录页面的 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 会还原更改,但看起来用户记录会一直保留在数据库中,直到第二个场景块。
如何确保在第一个场景之后清理数据库?
我按照这个 post
配置了数据库清理器# 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
使用这些设置:
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
确保在 spec/rails_helper.rb
中有以下配置RSpec.configure do |config|
config.use_transactional_fixtures = true
end
我们的想法是从一个干净的数据库开始每个示例,创建该示例所需的任何数据,然后通过在示例结束时简单地回滚事务来删除该数据。
我错误地假设 spec/support 文件夹中的配置文件是自动加载的,但事实证明我不得不取消注释 spec/rails_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
DatabaseCleaner 配置文件是正确的,只是根本没有加载。
如果您在测试的方法中使用 MySQL 和更改表(重置自动增量或任何 DDL 操作),事务策略 will fail 和您的数据库将不会清洁。
为了修复,您必须像这样声明一个配置块:
config.before(:each, :altering_database => true) do
DatabaseCleaner.strategy = :truncation
end
并将此配置添加到您的测试上下文中:
context "when you alter the DB", :altering_database => true do...
注意:这会减慢您的测试速度,因此请注意不要滥用它。
config.before(:example) do
DatabaseCleaner.clean_with(:truncation)
end
对我有用!