Skip to content

Instantly share code, notes, and snippets.

@andreypronin
Last active January 18, 2016 23:41
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save andreypronin/4950750 to your computer and use it in GitHub Desktop.
Save andreypronin/4950750 to your computer and use it in GitHub Desktop.
RSpec hooks I use with DatabaseCleaner. We can't use transactional fixtures with Selenium/Poltergeist, but it's an overkill to truncate/delete for non-JS specs. Thus this optimization here. Read more at http://railscasts.com/episodes/257-request-specs-and-capybara. Assumption (just in case): only javascript_driver is set to Poltergeist/Selenium …
config.use_transactional_fixtures = false
config.before(:suite) do
# Do truncation once per suite to vacuum for Postgres
DatabaseCleaner.clean_with :truncation
# Normally do transactions-based cleanup
DatabaseCleaner.strategy = :transaction
end
config.around(:each) do |spec|
if spec.metadata[:js] || spec.metadata[:test_commit]
# JS => run with PhantomJS that doesn't share connections => can't use transactions
# deletion is often faster than truncation on Postgres - doesn't vacuum
# no need to 'start', clean_with is sufficient for deletion
# Devise Emails: devise-async sends confirmation on commit only! => can't use transactions
spec.run
DatabaseCleaner.clean_with :deletion
else
# No JS/Devise => run with Rack::Test => transactions are ok
DatabaseCleaner.start
spec.run
DatabaseCleaner.clean
# see https://github.com/bmabey/database_cleaner/issues/99
begin
ActiveRecord::Base.connection.send(:rollback_transaction_records, true)
rescue
end
end
end
@andreypronin
Copy link
Author

An even cleaner, but slower, solution is http://devblog.avdi.org/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/.
Slower due to the fact that 'strategy=' needs to construct a strategy (check https://github.com/bmabey/database_cleaner/blob/master/lib/database_cleaner/base.rb). And with that approach it is done before each spec (and twice before truncations).

@andreypronin
Copy link
Author

UPDATE: 2nd version of database cleaning part in spec_helper:

  1. use transactions for most specs;
  2. use deletion for javascript (separate connections) & cases when you need to test smth that relies on commits (e.g. with after_commit callbacks).
    Plus: rollback_transaction_records to work around certain problems - see DatabaseCleaner/database_cleaner#99

@nozpheratu
Copy link

Thanks for sharing this, gave me a nice 15-20 second speed boost on my small test suite. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment