We are a software consultancy based in Berlin, Germany. We deliver
high quality web apps in short timespans.

Upstream Agile GmbH

Railsconf Europe 2007 Roundup 1 (rspec)

September 24, 2007 by alex

Last week was RailsConf 2007 in Berlin. Only a couple of days have passed and it already seems so far away. Time for some blogging before everybody forgets that it even took place and nobody’s going to read this :) So here’s the interesting part of the sessions I attended:

A Half-day of Behavior-driven Development on Rails (rspec)

This was the first session on tutorial day and for me one of the most interesting. It basically gave a looong introduction to behavior driven design, how it evolved from things like TDD and who realized what while enganged in which project back in the good old times. One of the interesting parts for me was when they talked about the whole story writing/specification process. I had heard most of it before but it was a good refreshment. The central statement was to write “Software that matters”, and to achieve this, you’d have to get the specs right - as we XPers know this should be done by collecting user stories. The suggested format for such a story was this:

As a [role] I want [feature] so that [outcome]

Example:

As an administrator I want to see the list of users so that i can choose which one to delete.

Great, a template for writing story cards. Following the story, you need an acceptance test that verifies that the story has been implemented. The suggested format is this:

given [context] given [more context] when [event] when ... then [outcome] then ...

Example:

Given i am logged in as root Given a list of users When i view /users Then i see all the users

Now in the early days you would write this on a story card or on some other maybe non-digital, maybe digital surface, but you would not do this: run the acceptance test as code. (I’m aware there are some projects who’ve tried/done it but I’ve never found one too convincing and really used it). Now you can. They actually implemented a new feature in rspec trunk called StoryRunner to do exactly this and here’s how it looks:

Story 'As an administrator
I want to see the list of users
so that i can choose which one to delete.' do

Scenario 'logged in as root with 2 users in system' do

  Given 'i am logged in as', 'root' do |name|
    @user = create_user :name => name
    post /sessions/create, :name => name, :password => @user.password
  end

  Given 'a list of users' do
   @users = [create_user, create_user]
  end

  When 'i view', '/users' do |location|
    get location
  end

  Then 'i see all the users' do
    @users.each do |user|
      response.should have_text(user.name)
    end
  end

  def create_user
    ...
  end

end

end

How cool is that, but it doesn’t even stop here. You can now reuse the code blocks you have created (!!):

Scenario 'logged in admin with no users in the system'
  Given 'i am logged in as', 'root'
  Given 'there are no users' do
    User.delete_all
  end
  When 'i view ', '/users'
  Then 'i see a message that there ar no users' do
    response.should have_text 'nobody there'
  end
end

Ok, technically speaking it’s actually not much more than reusing code but the way it’s done in StoryRunner, you are almost forced to create your own, application specific testing DSL! (Did I mention how fantastic this is?). For a better example which includes a “normal” rails integration test and compares it to an rspec story implementation see the evang.ei.st blog.

Of course they also showed the “usual” rspec stuff (referred to as “classic rspec”) for specing models and controllers. I you haven’t already go back to the evang.eli.st and check out Easy Controller Tests and Expressing Intent Through Expectations - a really good (imho) introduction on writing controllers using test spec first.

Enough for now, I’m sure there will be more on rspec here soon.