Alex Rivera | Logout

Rspec, Cucumber: best speed database clean strategy

Asked 2011-03-21T13:54:02.397
14

I would like to increase the speed of my tests.

  1. Should I use use_transactional_fixtures or go with the database_cleaner gem?
  2. Which database_cleaner strategy is the best? I noticed that after migration from :truncation to :transaction my more than 800 examples run about 4 times faster!
  3. Should I turn off use_transactional_fixtures when I use database_cleaner :transaction?
  4. Is it true that the best strategy for rack_test is :transaction?
  5. What is the best practices for changing strategy on the fly from :transaction to :truncation when using selenium or akephalos?

P.S. Mysql, Rails 3, Rspec2, Cucumber

P.P.S. I know about spork and parallel_test and using them. But they are offtopic. For example, Spork save about 15-20 sec on whole suite run, but changing from :transaction to :truncation dramatically increase running time from 3.5 to 13.5 minutes (10 minutes difference).

Edit
Report

2 Answers

5

1., 2. & 4., You should use transactions (either with use_transactional_fixtures or transactions support from the database_cleaner gem) if you are using capybara's default engine, rack_test. As you noted, using transactions are substantially faster than using a truncation strategy. However, when database writes can go through different threads (as with selenium) transactions won't work. So you'll need to use truncation (or force everything to go through one db thread--another option).

3. Yes, you should turn off use_transactional_fixtures when using the database_cleaner gem since the gem natively support transactions. If you only need transactions then just use_transactional_fixtures and never load the database_cleaner gem.

5. The following code will switch between :transaction and :truncation on the fly. (Tested this with rspec, capybara, rails3.)

Features This should give you the best of both worlds. The speed of rack_test when you don't need to test javascript stuff and the flexibility of selenium when you do.

Also this code takes care of repopulating seed data in cases where it is needed (this method assumes you use seeds.rb to load your seed data--as is the current convention).

Add the following code to spec_helper.

config.use_transactional_fixtures = false
RSpec.configure do |config|
  config.before(:suite) do
    require "#{Rails.root}/db/seeds.rb"
  end

  config.before :each do
    if Capybara.current_driver == :rack_test
      DatabaseCleaner.strategy = :transaction
    else
      DatabaseCleaner.strategy = :truncation
    end
    DatabaseCleaner.start
  end
  config.after(:each) do
    if Capybara.current_driver == :rack_test
      DatabaseCleaner.clean
    else
      DatabaseCleaner.clean
      load "#{Rails.root}/db/seeds.rb"
 
answered 2012-07-20T07:06:55.917
-1

Have you used Spork ? It greatly enhances speed.

answered 2011-03-21T17:27:09.333

Your Answer