My current testing tool of choice is Cucumber. Cucumber itself integrates well with other tools. One of those tools is Webrat, which allows you to access your application without a browser and to perform actions like clicking on a link or filling out forms. It works fine with Rails 2.3.x, but not with Rails 3 (at least I was not able to make it work, and on RailsPlugins.org the current version of Webrat, 0.7.2.beta.1, is listed as “Maybe [working] with Rails 3″). Fortunately, there is an alternative working with both Rails versions: Capybara. And so I decided to make the switch from Webrat to Capybara.
Before making the switch, I recommend to run your Cucumber tests to ensure all tests pass:
$ cucumber features
As usual when adding new dependencies, you have to modify the Gemfile of your app. Replace the Webrat entry with:
gem "capybara", "0.3.9"
and run:
$ bundle update
With Capybara installed, you have to setup Cucumber to use Capybara by running one of the following commands:
// Rails 2.3.9
$ script/generate cucumber --rspec --capybara
// Rails 3.0.0
$ rails generate cucumber:install --rspec --capybara
Now, you are ready to run the tests again. If you are lucky, all tests pass, which means there is nothing more to do. However, I think it is more likely you will get a bunch of errors and maybe even some failing tests.
The errors I got were “undefined method” errors. They are relatively easy to fix by replacing the no longer existing Webrat methods with their Capybara counterparts. In the following code block I list some examples:
# Webrat
field_with_id('openid_identifier').value.should =~ /invalid OpenID/
# Capybara
find_field('openid_identifier').value.should =~ /invalid OpenID/
# Webrat
response.should contain('Previous')
# Capybara
page.should have_content('Previous')
# Webrat
assert_have_selector('.author', :count => 1)
# Capybara
page.should have_css('.author', :count => 1)
# Webrat
assert_have_xpath("//span[@id='#{id}']", :content => expected_count)
# Capybara
page.should have_xpath("//span[@id='#{id}']", :text => expected_count)
The trickiest part to fix was the failing test. To test some “remember me” functionality I manually set a cookie, and this no longer worked with Capybara:
cookies[:remember_me_id] = remember_me_id
After some searching I found a Gist from Nicholas Rutherford in which he dealt with cookies. Thanks to his code I could set my cookie with the following snippet:
cookies = Capybara.current_session.driver.current_session.instance_variable_get(:@rack_mock_session).cookie_jar
cookies[:remember_me_id] = remember_me_id
And with that, my switch to Capybara was complete. Any questions?
