Read more

How to set up database_cleaner for Rails with Cucumber and RSpec

Dominik Schöler
January 23, 2015Software engineer at makandra GmbH

Add gem 'database_cleaner' to your Gemfile. Then:

Cucumber & Rails 3+

# features/support/database_cleaner.rb

DatabaseCleaner.clean_with(:deletion) # clean once, now
DatabaseCleaner.strategy = :transaction
Cucumber::Rails::Database.javascript_strategy = :deletion

Cucumber & Rails 2

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

The latest available cucumber-rails for Rails 2 automatically uses database_cleaner when cucumber/rails/active_record is required -- but only if transactional fixtures are off. To have database_cleaner work correctly:

  1. Add the attached database_cleaner.rb to features/support/
  2. Make sure features/support/env.rb contains the following lines in this order:
# features/support/env.rb

require 'features/support/database_cleaner'
require 'cucumber/rails/active_record'
require 'cucumber/rails/world'
Cucumber::Rails::World.use_transactional_fixtures = false

RSpec

# spec/support/database_cleaner.rb

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:deletion)
  end

  config.around do |example|
    DatabaseCleaner.start
    example.run
    DatabaseCleaner.clean
  end
end
# spec/spec_helper.rb

RSpec.configure do |config|
  config.use_transactional_fixtures = false
end 

Important Don't use a combination of config.before and config.after here otherwise around hooks are not within the transaction and your database is therefore not cleaned properly between examples due to execution order, e.g.

around do |example|
  superuser_power = Power.new(create(:user, :superuser))
  Power.with_power(superuser_power) do
    # before-block will be run here, DB snapshot will be created
    example.run
    # after-block will be run here, restore of DB
  end
end

Comments

  • clean_with wipes the database just when it is called. The above configurations make sure the test database(s) are emptied up-front.
  • The :transaction strategy does not work with Selenium.

Also see Understanding database cleaning strategies in tests.

Dominik Schöler
January 23, 2015Software engineer at makandra GmbH
Posted by Dominik Schöler to makandra dev (2015-01-23 12:06)