Showing posts with label webrat. Show all posts
Showing posts with label webrat. Show all posts

Sunday, 30 November 2008

Writing User Stories with Merb, Cucumber, merb_cucumber and webrat

I decided to try out cucumber and webrat for writing user stories in my sample merb application. Merbbit is a merb-based web app for community-driven link submission. Think Digg, Reddit etc.

I had used user stories before but I found so time-consuming as to be of little use. I was hoping that using webrat's shortcuts, the new improved story runner Cucumber and factory_girl would speed up writing these tests.

Getting setup was quite pain-free.

sudo gem install cucumber webrat david-merb_cucumber --no-ri --no-rdoc
merb-gen cucumber --session-type=webrat


This will also install a sample login feature that should pass if you’re using merb-auth. I was using merb-auth but when I ran:

rake features
The feature failed with the error:

Could not find field labeled "login"

This was because I had changed the login field in the login form from 'login' to 'email'. This was easy to fix. In features/login.feature I just changed

And I fill in "login" with "i_dont_exist"
to
And I filled in "email" with "i_dont_exist"
And it worked!

One of the first cool things I notice about cucumber is how much more colourful it is than the original user stories. It also discreetly tells you what line and what file the step starts on. This can be useful when you forget which file you wrote the matching step in.
And I fill in "password" with "and_i_dont_have_a_password"  # features/steps/common_webrat.rb:16
The failed login scenario of the Login feature comes for free. I now needed to write a successful login scenario.
Scenario: Successful Login
Given I am not authenticated
And an user exists with login "me@example.com" and password "secret_password"
When I go to /login
And I fill in "email" with "me@example.com"
And I fill in "password" with "secret_password"
And I press "Log In"
Then the login request should succeed
And I should see "me" in user_login
I had to write some new steps before I could run this scenario.

For the step "And a user with login "me", email "me@example.com" and password "secret_password"" I needed to create a step that would populate the database with a user. I decided to use factory girl
$ sudo gem install thoughtbot-factory_girl

add require 'factories' to features/env.rb

features/factories.rb:
gem 'thoughtbot-factory_girl'
require 'factory_girl'

Factory.define :user do |u|
u.login 'me'
u.email 'me@example.com'
u.password 'password'
u.password_confirmation 'password'
u.active 'active'
end

require 'features/steps/common_factory_steps'

features/steps/common_factory_steps:
Given /^a user with login "(.+)", email "(.+)" and password "(.+)"$/ do |login, email, password|
Factory(:user, :login => login, :email => email, :password => password, :password_confirmation => password)
end
For the step "Then the login request should succeed", merb_cucumber comes with a "Then the login request should fail" but not a succeed step. It's easy to create one though.
Then /^the (.*) ?request should succeed/ do |_|
response.should be_successful
end
I can't see an easy way using merb to tell if a specific template has been rendered like in rails integration testing (render_template) so I settled for just verifying that the users login "me" appears inside an element called 'user_login'.
Then /^I should see "(.+)" in (.+)$/ do |message, id|
response.should have_xpath("//*[@id=\"#{id}\" and text()=\"#{message}\"]")
end
This step could be used to test for any piece of text inside an element with a given id.

Sources that helped:
http://github.com/david/merb_cucumber/tree/master
http://github.com/brynary/webrat/tree/master
http://rubybling.blogspot.com/2008/10/merbcucumber-almost-baked.html