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.