Syntax highlighting for plain text user stories

Again a post about plain text user stories

My friend Iain was busy making syntax highlighting in VIm for rSpec’s plain text user stories. I thought it would be nice to modify the Google Syntax Highlighting plugin for WordPress, so you can have nicely highlighted stories on your blog.

First install the WordPress plugin and make sure it works. After, download my modified version of this plugin.

Whenever you want to post a plain-text user story, use the pre tag with ‘code’ as name and ‘story’ as class attribute to indicate it’s a user story.

This is how it looks:

Story: Arrangement

As a user
I want to invite people
So I have more chance of winning an arrangement

Scenario: Browsing the homepage
Given a clean database
When the user goes to /
Then the page should contain the text 'alledaagse'

Scenario: Choosing an arrangement
When the user chooses the godinfrankrijk arrangement
Then the page should contain the text 'God in Frankrijk'
And the page should contain the text 'voor te stellen'

Scenario: Inviting a person
Given a clean session
When the user chooses the ster arrangement
Then the page should contain the text 'leven als een ster'
When the user types 'His Name' into the invitee_name field
And the user types 'Street 13' into the invitee_address field
And the user types '1234AB' into the invitee_zip field
And the user types 'Rotterdam' into the invitee_city field
And the user types '0101234567' into the invitee_phone field
And the user clicks on the radiobutton labelled vrouw
And the user clicks the submit button
Then the page should contain the text 'mijn gegevens'

Book on BDD in Ruby with RSpec

RSpec book

I was browsing through this excellent presentation given by Dave Astels and David Chelimsky at RubyConf2007. Turns out that David Chelimsky and Aslak Hellesøy are working on a book about Behaviour Driven Development using RSpec.

The presentation is an excellent introduction for anyone thinking about moving to RSpec. It tells you a bit about the (rather short) history of the framework and the differences between BDD and TDD.

It also shows off the awesome plain-text stories I posted about earlier.

Story-based acceptance testing

In my previous post I talked a bit about Behaviour Driven Development and RSpec’s beautiful syntax for writing specifications.

This week I stumbled upon acceptance testing in RSpec and a very pretty way of writing those tests.

A simple acceptance test would look like this:

Story: A user sends an invitation

The invitation page should allow users to invite friends

Scenario: Sending an invitation
Given a new unused email
When the user goes to /invite/create
And the user types 'Test' into the invite_name field
And the user types 'User' into the invite_surname field
And the user types 'someemail@email.com' into the invite_email field
And the user clicks the commit button
Then the page should contain the text 'Test User was invited'

Scenario: Sending an invitation to an already used email address
Given an already used email address someemail@email.com
When the user goes to /invite/create
And the user types 'Test' into the invite_name field
And the user types 'User' into the invite_surname field
And the user types 'someemail@email.com' into the invite_email field
And the user clicks the commit button
Then the page should contain the text 'Email already exists'

Now these tests don’t do anything by themselves, you need to run them against the application.
This is where Selenium comes in. Using RSpec’s story runner, you can feed these plain-text stories to Selenium.

Selenium will open your web application in a browser and go to URL’s, enter data, click buttons/checkboxes/radiobuttons. It’s kinda spooky to see your browser navigate to pages by itself 😉

Here’s another test that checks the login function

Story: A user logs in

Scenario: Logging in fails
Given a user with username 'Arie' and password 'test'
When the user goes to /login
And the user types 'Arie' into the login field
And the user types 'not-test' into the password field
And the user clicks the commit button
Then the page should contain the text 'Unable to login'

Scenario: Logging in successfully
Given a user with username 'Arie' and password 'test'
When the user goes to /login
And the user types 'Arie' into the login field
And the user types 'test' into the password field
And the user clicks the commit button
Then the page should contain the text 'Logged in'

For now I’m not planning on covering my entire application with tests like this. I’m just going to make a few tests that I can show to my school when I finish my internship.

Behaviour Driven Development

I’m currently doing an internship as a final part of my study. Luckily I’ve been able to find a company where I can use Rails to create a new application.

One of the choices I made for the development is the use of BehaviourDrivenDevelopment (BDD), which is a variation on TestDrivenDevelopment (TDD).

Rspec is a BDD-framework for Rails. It features a beautiful way of expressing the expected behaviour of your application.

Here’s an example of the expected behaviour of a user controller

  it "should flash a notice after succesful signup" do
    User.should_receive(:new).with({"name" => 'Arie'}).and_return(@user)
    @user.should_receive(:save!)
    post 'signup', {:user => {:name => 'Arie'}}
    flash[:notice].should eql(_('Thanks for signing up, you will have to activate your account before you can log in'))
  end

And an example of expected behaviour of a user model

  specify "should be invalid with invalid zip code" do
    @user.attributes = valid_user_attributes.except(:zip)
    @user.zip = 'tralalalalala'
    @user.should_not be_valid
    @user.errors.on(:zip).should eql(_('is invalid'))
    @user.zip = '1234AB'
    @user.should be_valid
  end

The main idea of TDD and BDD is that you write these tests or specifications before writing the actual code. The basic workflow while doing BDD/TDD is:

1. Write tests/specifications

2. Run tests/specifications

3. See them fail because there’s no code yet

4. Code until tests no longer fail

It takes some discipline to strictly follow this pattern, because a future piece of code might seem so trivial, that you want to code it immediately.

rcov resultsWriting the specifications like this takes some time, but you’ll easily make up for it while you’re coding your application. You can use Rcov to check if your specifications cover all your code. When your specifications cover all your code with sensible tests, you can easily refactor your code, because the specifications will make sure your new code works properly.

Also, you can generate human-readable specifications from these rspec files, here’s a snippet of how that looks:

A user
– should be invalid without a username
– should have unique login name
– should be invalid without an email
– should be invalid if email is not between 3 and 100 characters in length
– should have unique email address

The UserController
– should redirect to profile after successfull activation
– should flash a notice when a valid activation code was used
– should flash an error when an invalid activation code was used

In combination with AutoTest, BDD is already saving me a lot of time during development.

Whenever I’ve changed some of my sourcecode or specifications, the specifications get tested automatically. If something breaks, there’s a small error popup, so you know you should check the AutoTest window for the test where it failed.

autotest error

Spot the typo

‘The User Controller should flash an error when an invalid activation code was used‘ FAILED
expected “Unable to activate the account.”, got “Unable to activate the accnt.” (using .eql?)

./spec/controllers/user_controller_spec.rb:29:
script/spec:4:

If all tests pass you get a cheerful message.

AutoTest success