by Paul Elliott, May 11, 2010, content retrieved using Internet Archive's Wayback Machine
Integration testing is critical for modern web applications. It provides a chance to exercise all the features of your site in a real or mock browser and make sure that everything still work correctly with any changes made. It plays a key role in insuring the quality of your application and that your users have as bug-free an environment as possible.
Integrating it into your existing rspec setup is a breeze, too. I am a big fan of Jonas Nicklas’ Capybara (http://github.com/jnicklas/capybara), which is a great gem that lets you mix and match web drivers over a common interface and allows you to test specific functions of your site with the appropriate platform. You can easily use it directly with RSpec to write a comprehensive integration test suite for your application.
Let’s get started by running rake
. If you don’t have a passing test suite right now, then shame on you! You need to fix that before doing anything else. If you don’t have a test suite at all, then...well...thanks for reading this and hopefully you will get off to a good start when you’re done.
Once you are all green, setup the latest capybara and rspec gems. Update your Gemfile
with the necessary includes.
source :gemcutter
...
group :test do
gem 'capybara', '0.3.7'
gem 'rspec-rails', '1.3.2'
gem 'factory_girl', '1.2.4'
...
end
Run bundle install --relock
. If you are updating or installing RSpec for the first time, be sure to run the generator to get your configuration up to date:
script/generate rspec
One last piece of setup, we need to update the spec_helper.rb with the settings for Capybara.
require 'capybara/rails'
require 'capybara/dsl'
Spec::Runner.configure do |config|
config.use_transactional_fixtures = true
config.use_instantiated_fixtures = false
config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
config.include(Capybara, :type => :integration)
end
Just to make sure all this is working properly, go ahead and run rake
again. If this doesn’t work, you need to fix whatever the problem is before moving on.
Now on to Capybara! By default it uses the rack-test driver, which is similar to webrat in that it is headless and does not run javascript. Unless you have a very javascript intensive app, the rack-test driver should handle the majority of your test cases. The really cool thing about Capybara is that you can use another driver like selenium when you need javascript and rack-test when you don’t.
Now let’s test a simple sign in process. Create a file called spec/integration/guest_signs_in_spec.rb
and fill it in like so. Be sure to change the field, button, and link labels to match your actual screens.
require 'spec_helper'
context 'as a guest on the sign in page' do
# Make sure your factory generates a valid user for your authentication system
let(:user) { Factory(:user) }
# Browse to the homepage and click the Sign In link
before do
visit root_path
click 'Sign In'
end
context 'with valid credentials' do
# Fill in the form with the user’s credentials and submit it.
before do
fill_in 'Email', :with => user.email
fill_in 'Password', :with => 'password'
click 'Submit'
end
it 'has a sign out link' do
page.should have_xpath('//a', :text => 'Sign Out')
end
it 'knows who I am' do
page.should have_content("Welcome, #{user.email}!")
end
end
context 'with invalid credentials' do
# No form entry should produce an error
before do
click 'Submit'
end
it 'has errors' do
page.should have_xpath("//div[@id='errorExplanation']")
end
end
end
That is a trivial example and you would typically want to make more numerous and comprehensive asserts than that, but it should get you going with your first test.
Now that you have a modern integration test setup, I expect to see the quality of your app improve dramatically! Happy TDD’ing!