我已将database_cleaner gem添加到我的rails应用程序中,以便在规范之间清理我的数据库。这是我对database_cleaner的当前配置,位于spec/spec_helper.rb
:
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
DatabaseCleaner.start
DatabaseCleaner.clean
end
config.before(:each) do
DatabaseCleaner.clean
end
config.after(:each) do
DatabaseCleaner.clean
end
config.after(:suite) do
DatabaseCleaner.clean
end
现在,只要运行的每个最后一个规范通过或失败,此配置都可以正常工作。
然而,如果出现错误(rspec没有给你一个像minitest那样漂亮的小E
,它会抛出这样的东西:
09:17:32 - INFO - Running: spec
/usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/validations.rb:57:in `save!': Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)
),数据库未清理!错误之前的规范中的残留数据保留在数据库中。我想这是因为database_cleaner不会将错误的规范视为完成,因此不会清理数据库。
现在,在您再次运行规范之前,这并不会造成任何伤害。然后残差数据会产生类似于此的错误:
09:17:32 - INFO - Running: spec
/usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/validations.rb:57:in `save!': Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)
解决此错误很简单;运行rails_env=test rake db:reset
或启动数据库shell并使用sql语句清空相关表将清除此数据并允许规范顺利运行。
但是,这很烦人。我的任何一个规格中的一个错误的角色(任何使它错误而不是失败的东西)都会导致我的整个测试工作流程堵塞,就像自动武器的发射机制一样!
您对database_cleaner的建议是什么?您是否有任何允许清理数据库的示例配置,即使在错误测试的情况下也是如此?
我正在使用后卫运行我的rspecs,并进一步增加了factory-girl:
的Gemfile:
source 'https://rubygems.org'
group :development do
gem 'capistrano'
gem 'rb-fsevent'
gem 'debugger'
end
group :development, :test do
gem 'rspec-rails', '~> 2.14.0'
gem 'sqlite3'
gem 'guard-rspec'
gem 'guard-livereload', require: false
gem 'guard-shell'
gem 'webrick', '~> 1.3.1'
end
group :test do
gem 'factory_girl_rails'
gem 'capybara', '~> 2.2.0'
gem 'selenium-webdriver'
# capybara-webkit gem requires an application called 'libqtwebkit-dev' to build. To install 'libqtwebkit-dev' in Ubuntu, run
# sudo apt-get install libqtwebkit-dev
# gem 'capybara-webkit'
gem 'rb-readline'
gem 'launchy'
gem 'database_cleaner'
end
group :production do
gem 'pg'
# gem 'puma'
end
# rails version
gem 'rails', '4.0.1'
# standard library
gem 'sass-rails', '~> 4.0.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 1.2'
group :doc do
gem 'sdoc', require: false
end
# custom
gem 'activeadmin', github: 'gregbell/active_admin'
gem 'devise'
gem 'simple_form'
规格/ spec_helper:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
config.include Capybara::DSL
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
DatabaseCleaner.start
DatabaseCleaner.clean
end
config.before(:each) do
DatabaseCleaner.clean
end
config.after(:each) do
DatabaseCleaner.clean
end
config.after(:suite) do
DatabaseCleaner.clean
end
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# config.include RSpec::Rails::RequestExampleGroup, type: :feature
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
end
答案 0 :(得分:8)
您想要更改此
config.after(:suite) do
DatabaseCleaner.clean
end
对此:
config.after(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
否则,它将简单地回滚事务,这将留下在事务开始之前存在的任何数据。
答案 1 :(得分:0)
这对我有用:
DatabaseCleaner.strategy = :truncation
...
before(:each) do
DatabaseCleaner.clean
end
答案 2 :(得分:0)
请出示规格。
您需要确保您的设置/拆卸是在之前/之后/其等等语句中完成的。
如果您在上述之外进行了设置和变量赋值,并且只是“在测试中”,则测试将在您遇到时弹出。如果在设置中完成,则可以避免此问题。
你不应该像你一样尝试与内部进行跳汰。与Ror中的许多事情一样,如果你这样做,你很可能会用你的代码“走出去”。 Rails旨在成为一个为您完成所有单调乏味的框架,您只需要保持“轨道”。
答案 3 :(得分:0)
add a file:
# RSpec
# spec/support/database_cleaner.rb
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
end
and uncomment
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
in spec/rails_heper.rb