Mixing DatabaseCleaner transaction and truncation strategies

RSpec by default issues a database transactional rollback that is executed after the completion of a block. When using Capybara with the :js option (to enable testing with Selenium or Webkit), the transactional rollback offered by RSpec is unusable as the browser is loaded via a separate thread and has a separate database connection. Thus any uncommitted data cannot be read by the browser.

Most people suggest employing DatabaseCleaner using a truncation strategy to overcome this deficiency. The performance of cleaning via truncation vs transaction depends on the size of data – with smaller fixtures, transactions are preferable.
Instead of using one or the other, we can mix strategies to have the best of both worlds:

config.use_transactional_fixtures = false # Using DatabaseCleaner instead

config.before(:suite) do
DatabaseCleaner.strategy = :transaction # Default strategy
DatabaseCleaner.clean_with(:truncation) # Initially clean with truncation
end

config.before(:each, type: :request) do
# Swap to truncation as Selenium runs in separate thread with a different
# database connection
DatabaseCleaner.strategy = :truncation
end

config.after(:each, type: :request) do
# Reset so non-request specs can use transaction
DatabaseCleaner.strategy = :transaction
end

config.before(:each) do
DatabaseCleaner.start
end

config.after(:each) do
DatabaseCleaner.clean
end

On my current test suite of around 461 tests with 73 request specs, this dropped the run time by just over a minute.


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *