Search code examples
ruby-on-railsrspeccapybaradatabase-cleaner

Database Cleaner: Clean vs truncation


What is the difference between the following?

  • DatabaseCleaner.clean_with(:truncation)
  • DatabaseCleaner.clean

What i'm trying to figure out is what is the best way to clean up a before(:all) hook in my tests (performance wise) using database cleaner. My before(:all) hook just creates a ton of factories and creates some associations between them. Currently, i'm just loading them all in a before(:each) not having to worry about the cleanup afterwards.

My current strategy looks like:

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

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do |example|
    DatabaseCleaner.strategy = example.metadata[:js] ? :truncation : :transaction
    DatabaseCleaner.start
  end

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

So in addition to my previous question, what should my after(:all) look like?


Solution

  • What is the difference between the following?

    • DatabaseCleaner.clean_with(:truncation)
    • DatabaseCleaner.clean

    The difference is pretty straightforward: in the first case you're telling DatabaseCleaner to clean your db now with truncation strategy, and in the second case DatabaseCleaner will clean your db using currently configured strategy.

    I think your setup is pretty good already. Since creating a ton of factories (as you said) in before(:all) hook is quite rare, you just need to add to that specific test after(:all) hook to put the db back to stable state.

    Cleaning with transaction won't work, since before(:all) is not wrapped in transaction. You're left with 2 options here:

    1. after(:all) { DatabaseCleaner.with(:truncation) }

    2. after(:all) { DatabaseCleaner.with(:deletion) }

    In order to choose between these two, as documentation clearly states, you have to measure and choose what's fastest for you, or just pick some if it doesn't matter.