Wie kann ich meine Datenbank zwischen fehlerhaften rspec-Angaben bereinigen?

Ich habe der Rails-Anwendung den Edelstein database_cleaner hinzugefügt, um meine Datenbank zwischen den Spezifikationen zu bereinigen. Hier ist meine aktuelle Konfiguration für database_cleaner inspec/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

Diese Konfiguration funktioniert nun einwandfrei, solange jede zuletzt ausgeführte Spezifikation erfolgreich ist oder fehlschlägt.

Im Falle eines Fehlers (rspec gibt Ihnen jedoch kein nettes kleinesE Wie ein Minitest wirft es solche Dinge aus:

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)

), die Datenbank wird nicht gesäubert! Restdaten aus der Spezifikation unmittelbar vor dem Fehler verbleiben in der Datenbank. Ich nehme an, das liegt daran, dass database_cleaner die fehlerhafte Spezifikation nicht als abschließend ansieht und die Datenbank daher nicht bereinigt.

Nun, das schadet nicht wirklich, bis Sie Ihre Spezifikationen erneut ausführen. Die Restdaten verursachen dann analog dazu einen Fehler:

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)

Es ist einfach genug, diesen Fehler zu umgehen. Laufenrails_env=test rake db:reset Wenn Sie Ihre Datenbank-Shell starten und die entsprechenden Tabellen mit SQL-Anweisungen leeren, werden diese Daten gelöscht, und die Spezifikationen können problemlos ausgeführt werden.

Dies wird jedoch ärgerlich. Ein falsches Zeichen in einer meiner Spezifikationen (etwas, das es eher fehlerhaft als fehlerhaft macht) führt dazu, dass mein gesamter Test-Workflow blockiert, fast wie der Zündmechanismus einer automatischen Waffe!

Was sind Ihre Vorschläge zu database_cleaner? Haben Sie Beispielkonfigurationen, mit denen die Datenbank auch im Falle eines fehlerhaften Tests bereinigt werden kann?

Ich benutze Wache, um meine rspecs laufen zu lassen, die mit Fabrikmädchen weiter vergrößert werden:

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

Antworten auf die Frage(4)

Ihre Antwort auf die Frage