Search code examples
ruby-on-railsrspeccapybaraguard

Rspec with capybara strange behavior when guard is running


I've created a couple of tests using rspec+capybara. tests code

When i run them with rspec they all pass

git:(master) ✗ rspec    
Rack::File headers parameter replaces cache_control after Rack 1.5.
WARNING:  there is already a transaction in progress
NOTICE:  there is no transaction in progress
.WARNING:  there is already a transaction in progress
NOTICE:  there is no transaction in progress
.WARNING:  there is already a transaction in progress
NOTICE:  there is no transaction in progress
.WARNING:  there is already a transaction in progress
NOTICE:  there is no transaction in progress
.WARNING:  there is already a transaction in progress
NOTICE:  there is no transaction in progress
.WARNING:  there is already a transaction in progress
NOTICE:  there is no transaction in progress
.WARNING:  there is already a transaction in progress
NOTICE:  there is no transaction in progress
.WARNING:  there is already a transaction in progress
NOTICE:  there is no transaction in progress
.

Finished in 32.54 seconds
8 examples, 0 failures

but if i use guard some tend to fail (some tests may fail, and may not from time to time)
Guard output

How this behavior can be explained? And how it can be fixed?

Update 1
I'm already using gem 'database_cleaner' with this config:

config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:transaction)
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = :transaction
  config.use_transactional_examples = true

Update 2
Changed couple of files https://github.com/Asmmund/notes/commit/a5e0a43d6247bb8f937fb7e9dcc8d8cfa7bfc4ea


Solution

  • Depending on how you've written your test, Capybara uses Selenium driver to run them. Selenium is not compatible with transactional fixtures and you should set that to false.

    Generally, you should try to avoid using Fixtures with Capybara (or most integration tests). A good integration test should rely minimally on fixtures and instead, create the data during the end-to-end flow (for example, user account should be created by simulated in-app actions, i.e. the test should submit a sign up form using Capybara). But odd cases are not avoidable, where you might need to seed the DB with some data. Many people use factories such as FactoryGirl for this, with success.

    If your tests are selenium, your DB cleanup also needs to use truncation, not transaction, strategy.

    Checkout this tutorial as a more in-depth guide.

    NOTE: to save time, in your case, read it from bottom to top:

    http://asciicasts.com/episodes/257-request-specs-and-capybara