Faster Capybara Specs
How to use the database_cleaner gem without slowing everything down.
Being able to drive a real web browser using Rspec and Capybara is great for testing JavaScript features in Rails. But have you noticed a drastic slowdown in the execution of your specs after setting up Capybara? Here’s how to speed things back up.
Well-intentioned, but slow
If you’ve used Capybara and Rspec, you probably found that transactional fixtures won’t work with JavaScript specs. A quick search on the web will reveal this workaround:1
# Gemfile
gem 'database_cleaner', group: :test
# spec_helper.rb -- This workaround is slow!
RSpec.configure do |config|
# ...
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
However, this workaround is a very blunt instrument: it tells Rspec to truncate the database after every spec. But we don’t need the workaround for every spec, we need it only for JavaScript specs.
A faster solution
The trick is to still use the database_cleaner
gem, but specify the slow :truncation
strategy only when we need it, and fall back to the fast :transaction
strategy otherwise. Here’s how:
RSpec.configure do |config|
# ...
config.use_transactional_fixtures = false
config.before(:each) do
DatabaseCleaner.strategy = if example.metadata[:js]
:truncation
else
:transaction
end
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
Notice how we use the metadata to test whether or not an example uses JavaScript (i.e. whether js: true
was specified). Using this metadata, it’s easy to choose the appropriate database strategy on an example-by-example basis.
The result
Here’s how long it took to run rake spec
on one of my projects before we adopted this solution:
Finished in 3 minutes 39.44 seconds
And after:
Finished in 41.27 seconds
That’s an 80% speedup!
-
This sample
spec_helper.rb
workaround is taken from RailsCasts episode #257. If you aren’t familiar with Capybara’s JavaScript testing abilities, or you’re new to Capybara-based integration testing in general, definitely check out the screencast. Then come back to this article to learn about my speedup. ↩
You just read
Faster Capybara Specs
How to use the database_cleaner gem without slowing everything down.
Share this post? Copy link
About the author
Hi! I’m a Ruby and CSS enthusiast, regular open source contributor, software engineer, and occasional blogger writing from the San Francisco Bay Area. Thanks for stopping by! —Matt