Database Cleaner issue with Capybara webkit
Asked Answered
D

2

10

I am using Cucumber to write my integration tests and Database Cleaner to keep my db clean. Everything perfectly works as my tests don't require Javascript.

I can make these last tests pass using Capybara webkit, but then my db is not cleaned at all.

Here is my features/support/env.rb file:

require 'simplecov'
SimpleCov.start 'rails'
require 'cucumber/rails'

Capybara.default_selector = :css
Capybara.javascript_driver = :webkit

begin
  require 'database_cleaner'
  require 'database_cleaner/cucumber'
  DatabaseCleaner[:active_record].strategy = :transaction
rescue NameError
  raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end


Before do
  DatabaseCleaner.start
end

After do |scenario|
  DatabaseCleaner.clean
end

I tried something similar to this to check which driver is used by Capybara but it didn't work. I also tried the hack mentioned in the third part of this post but then nothing worked at all...

I really don't know how to achieve this and any help would be greatly appreciated.

Thanks in advance.

Dortch answered 11/4, 2013 at 9:33 Comment(0)
C
24

Quick answer:

Configure your JavaScript tests to use truncation instead of transactions:

DatabaseCleaner.strategy = :truncation

Longer explanation:

The transaction strategy doesn't work well with JavaScript tests, because most JavaScript-capable capybara drivers run the tests in a different thread than the application code.

Here's a basic outline of the process:

  • Capybara boots up your rack application using webrick or thin in a background thread.
  • The main thread sets up the driver, providing the port the rack application is running on.
  • Your tests ask the driver to interact with the application, which causes the fake web browser to perform requests against your application.

This is necessary because it's difficult to make a fake browser that performs requests against an in-memory Rack application. In some database drivers, it isn't safe to perform queries from multiple threads against the same transaction.

The end result of this is that you need to commit transactions in your test code in order for the data to be visible in your application code. The easiest way to fix this is to use the truncation database cleaner strategy.

You can configure RSpec (or Cucumber) to use transactions for everything but JavaScript tests. This will be faster for non-JavaScript tests while still working for JavaScript tests.

Avdi Grimm has a good blog post on this subject that describes the solution in detail: http://devblog.avdi.org/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/

Cavan answered 12/4, 2013 at 17:0 Comment(0)
F
0

Transaction based startegies do not work with cucumber. The reason for this is that you have two separate processes running, one is running you app server and then other one doing actual requests. There are different ways around this, but they are dirty hacks. The clean solution is to use truncation as you DatabaseCleaner strategy.

DatabaseCleaner.strategy = :truncation

Before do
  DatabaseCleaner.clean_with :truncation
end
Flatting answered 11/4, 2013 at 16:40 Comment(2)
It's incorrect to say that transaction strategies don't work with Cucumber. It depends what Capybara driver you're using. With rack-test, everything is in-process, so the transaction strategy should work.Durante
Andy you are right. As I have @javascript enabled all the time I totally forgot about the old–good rack-test.Flatting

© 2022 - 2024 — McMap. All rights reserved.