我已将
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没有给你一个漂亮的小E像minitest,它会引发这样的事情:
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:重置或启动数据库shell并使用sql语句清空相关表将清除此数据并允许运行规范顺利运行.
然而,这变得很烦人.在我的任何规格中都有一个错误的角色(任何让它变得错误而不是失败的东西)会导致我的整个测试工作流程堵塞,就像自动武器的发射机制一样!
您对database_cleaner有什么建议?您是否有任何允许清理数据库的示例配置,即使在错误测试的情况下?
我正在使用后卫来运行我的工厂女孩进一步增强的rspecs:
的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
解决方法
你想改变这个
config.after(:suite) do DatabaseCleaner.clean end
对此:
config.after(:suite) do DatabaseCleaner.clean_with(:truncation) end
否则,它将简单地回滚事务,这将留下在事务启动之前存在的任何数据.