Seven years ago in 2012 I spoke at RubyConf China 2012. It was a technical talk on how to become a better developer, if you're interested…
Please also see this blog post on tweaking your ruby GC settings.
I use and love DatabaseCleaner, although historically I had never paid too much attention on the performance of its varies cleaning strategies - I’d always used
We use Postgres, and after digging around and finding out the difference between DELETE and TRUNCATE, I ended up improving our test suite speed by about 30-40% simply by tweaking the cleaning strategies.
RSpec.configure do |config| config.before :suite do DatabaseCleaner.clean_with :truncation DatabaseCleaner.strategy = :transaction end config.before do if example.metadata[:js] || example.metadata[:type] == :feature DatabaseCleaner.strategy = :deletion else DatabaseCleaner.strategy = :transaction DatabaseCleaner.start end end config.after do DatabaseCleaner.clean end end
Essentially, we want to
truncate the DB only once before the whole suite runs to ensure a clean slate DB, then we only want to use
deletion on Capybara tests, everything else should just use
transaction which is the fastest strategy.
Now, as a bonus, I have just discovered @amatsuda’s DatabaseRewinder which is a lightweight alternative that supports only ActiveRecord. It offers comparable performance with a much similar API.
RSpec.configure do |config| config.before :suite do DatabaseRewinder.clean_all end config.after do DatabaseRewinder.clean end end
By the way, we also use parallel_tests to scale our test suite to multiple processes, even on Travis CI and Wercker.
Hooray to faster tests! :)