A bit today about setting up and debugging Capybara with truncated fixtures. Capybara comes with an array of choices for a driver, the thing that actually runs your tests. You can emulate a user using a real browser (Firefox or Sarari), or you can emulate a headless browser.
Today I’m going to be focusing on setting this up with Selenium to have Firefox run your tests.
First, there is a special consideration about using a transactional or truncated database strategy. Also I ran into a hiccup debugging properly, so there are some notes below about how to setup the configuration files to be able to drop into the debugger in a Capybara-run test.
A transactional fixture strategy is on in which each test is wrapped in a database transaction, held in memory but not really committed to the database, and rolled back at the end of each test. This means that the test database starts the same way (with the same content) each time a new tests runs.
A truncated strategy, on the other hand, just flushes out the database after each test load. A truncated strategy uses a gem call database_cleaner to clean up the database after each run. The examples below show how to set up an app for a truncate strategy.
In typical old-style Rails tests, you created fixture data in YML files inside of test/fixtures/. This won’t work in a truncated strategy, because database_cleaner will clean out the database on each test run.
Assuming you have created a new app, be sure that these gems are installed
sudo gem install capybara libffi factory_girl_rails launchy redgreen cucumber-rails cucumber database_cleaner
Now create the cucumber setup:
rails generate cucumber:install -capybara
Basic template of a Gemfile
gem ‘rails’, ‘3.1.0’
group :production do
group :test do
# for use with Ruby 1.8.7…
# for use with Ruby 1.9…
Be sure to run bundle install after editing your Gemfile.
Now go to features/support/ and create a new file capybara_config.rb in this folder with the following contents.
Capybara.default_selector = :css
Capybara.default_driver = :selenium
DatabaseCleaner.strategy = :truncation
Cucumber::Rails::World.use_transactional_fixtures = true
There’s an explanation of this, along with three possible fixes, by jnicklas here. I got his suggestion #3 to work using the configuration above. (The last line is from his advice.) The key thing here is that when you switch Capybara to use Selenium (or webkit driver), your tests are no longer running in the same thread that your rails app is being tested against. This is critical because if you create a user
@user = User.create()
that database record will be wrapped in a transaction that will be not be recognized by the thread that is actually running your app. That means you might create a user and try to log-in with that user and won’t be able to because there will be no record in the DB. (There is actually a record, but Ruby sees the other thread as not sharing the transactions, so you can’t use, access, or test against it.)
I found that I need the requires for ‘rubygems’ and ‘ruby-debug’ in my Capybara config file (above) to get capybara to actually drop into the debugger (without it seemed to ignore the debugger command).