There have been a few times where I ran into problems with RSpec Capybara feature specs and
Now, the accepted answer the SO answer of simply turning off
transactional_fixtures in RSpec and using the
:truncation cleaning strategy in before/after hooks will work. However, when working in a large app (20+ minutes for full specs) this will slow your spec suite down dramatically. Why? From the DatabaseCleaner [documentation](DatabaseCleaner on which cleaning strategy is fastest:
For the SQL libraries the fastest option will be to use :transaction as transactions are simply rolled back.
After some research and lots of head banging, below is the configuration I have finally come to be happy with that gives us the best of all three worlds:
- DatabaseCleaner owns the cleaning and acts as we want it to.
- We get to add feature specs and increase coverage.
- Our test suite speed is only minimally impacted since we use
transactional_fixtureseverywhere except our feature specs.
# spec/spec_helper.rb RSpec.configure do |config| config.before(:suite) do DatabaseCleaner.clean_with(:truncation) end config.before(:each) do DatabaseCleaner.strategy = :transaction end config.before(:each, js: true) do DatabaseCleaner.strategy = :truncation end config.before(:each) do DatabaseCleaner.start end config.after(:each) do DatabaseCleaner.clean end config.before(:context, js: true) do self.use_transactional_fixtures = false end config.after(:context, js: true) do DatabaseCleaner.clean_with(:truncation) self.use_transactional_fixtures = true end end
How this works
Simply tag your feature specs with a
js: true block and everything will just work:
# spec/features/my_feature_spec.rb RSpec.describe "my feature", js: true do # do the testing stuff end
As mentioned before, this
js: true tag will disable RSpec's use of transactional fixtures and set the cleaning strategy to
One final note: this configuration will get more complicated if you use other test dependencies or configurations. Typically, you'll want to make sure those are loaded after
DatabaseCleaner is configured.