Perfect solution for testing Rails applications (RSpec, Cucumber, Capybara, Selenium 2.0)
Testing is hard. Writing tests takes a lot of time, and running them can also be a pain in the ass. However, we have a few new tools in Rails toolbox, that can make it simplier and more fun. Much simplier and much more fun!
Let's start with Capybara
Capybara is a Webrat replacement. It does well what Webrat tried to do: gives you nice DSL for writing your Cucumber feature steps, without being tightnly bound to particular backend. With Capybara you can switch between Selenium and Culerity easily and painlessly. To install Cucumber with Capybara support, run the following from within your Rails project:
$ sudo gem install cucumber cucumber-rails
$ ./script/generate cucumber --capybara --rspec
$ RAILS_ENV=cucumber rake gems:install
the last step will install Capybara itself, with a few additional libraries. You can now write your tests using nice Capybara DSL, for example:
Given /^I am signed in as "([^\"]*)"$/ do |user|
visit path_to("the home page")
fill_in("Login", :with => user)
fill_in("Password", :with => "testtest")
click_button("Submit")
end
and switch backends with simple configuration change in features/support/env.rb:
Capybara.default_driver = :selenium # will use Selenium as testing backend
Capybara.default_driver = :culerity # switch to Culerity
In fact you can switch between backends for different tasks, so it's perfectly possible to test part of your application which is web service with Webrat, and rest with Selenium or Culerity.
it's worth mentioning that Capybara works by default with Selenium 2.0 (not Selenium RC), a.k.a WebDriver, and will work right out of the box with it, provided you have Firefox installed.
Clearing database with DatabaseCleaner
Nice addition that Capybara includes by default is use of DatabaseCleaner. This nice gem, will clear your database, and what is cool, it works with MongoMapper as well as ActiveRecord and DataMapper.
To use it with MongoMapper, add the following to your features/support/env.rb:
require 'database_cleaner'
require 'database_cleaner/cucumber'
DatabaseCleaner.orm = 'mongo_mapper'
DatabaseCleaner.strategy = :truncation
Getting rid of annoying Firefox window
Cucumber with Selenium RC used to show and hide 2 Firefox windows at every scenario. Now, Capybara creates one window and is re-using it for all the scenarios. This is already better, but if you don't want to be annoyed with Firefox popping up on your desktop at all, you can hide it, if by some chance, you're on Unix-like system.
First, you'll need a Xvfb server:
$ sudo apt-get install Xvfb # if you're on Ubuntu/Debian
Now, you can run your tests "headless":
$ nohup Xvfb -ac -screen scrn 1024x768x24 :2.0 &
$ export DISPLAY=:2.0
$ rake cucumber:all
Why is that so cool?
The setup described above works great with Ruby 1.8 and also with Ruby 1.9. Using WebDriver instead of Selenium RC brings nice performance improvements. DatabaseCleaner provides "transactional fixtures" to applications that use MongoMapper or databases that don't support transactions. Running your scenarios in Xvfb has the additional advantage, that you can do it on your server, integrate with CI server (say, Integrity) and do some cool stuff like creating a screenshot after every step... but let's leave that for next post!