Jak mogę wyczyścić moją bazę danych między błędnymi specyfikacjami rspec?
Dodałem gem database_cleaner do mojej aplikacji railsowej, aby wyczyścić moją bazę danych między specyfikacjami. Oto moja obecna konfiguracja dla bazy danych_cleaner, znajdująca się wspec/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
Teraz ta konfiguracja działa poprawnie, o ile każda uruchomiona ostatnia specyfikacja przechodzi lub kończy się niepowodzeniem.
Jednak w przypadku błędu (rspec nie daje ci nic dobregoE
jak minitest, to rzuca takie rzeczy:
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)
) baza danych nie jest czyszczona! Pozostałe dane ze specyfikacji tuż przed błędem w bazie danych. Przypuszczam, że to dlatego, że database_cleaner nie traktuje błędnej specyfikacji jako kończącej, więc nie czyści bazy danych.
Teraz nie powoduje to żadnych szkód, dopóki nie uruchomisz ponownie specyfikacji. Dane rezydualne powodują następnie błąd analogiczny do tego:
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)
Poruszanie się po tym błędzie jest dość proste; bieganierails_env=test rake db:reset
lub odpalenie powłoki bazy danych i opróżnienie odpowiednich tabel za pomocą instrukcji sql usunie te dane i pozwoli na uruchomienie specyfikacji bez żadnych problemów.
Jest to jednak denerwujące. Jeden zły znak w którymkolwiek z moich specyfikacji (cokolwiek, co sprawi, że będzie on raczej błędny niż awaria) spowoduje, że cały mój proces testowania się zaciął, prawie jak mechanizm odpalania broni automatycznej!
Jakie są twoje sugestie dotyczące database_cleaner? Czy masz jakieś przykładowe konfiguracje, które pozwalają na czyszczenie bazy danych, nawet w przypadku błędnego testu?
Używam strażnika, aby uruchomić moje rspecy, które są dodatkowo wzbogacone o dziewczynę z fabryki:
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 / 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