Skip to content

Instantly share code, notes, and snippets.

@Macrow
Last active December 20, 2015 18:19
Show Gist options
  • Save Macrow/6175129 to your computer and use it in GitHub Desktop.
Save Macrow/6175129 to your computer and use it in GitHub Desktop.
Configure your JavaScript tests to use truncation instead of transactions

##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/

example

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

  config.before(:each) do
    if example.metadata[:js]
      DatabaseCleaner.strategy = :truncation
    else
      DatabaseCleaner.strategy = :transaction
    end
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment