Tag: truncation

  • 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.