Overview

RSpec is a Behaviour Driven Development framework for Ruby. It provides two frameworks for writing and executing examples of how your Ruby application should behave:

Story Framework

Start by writing a Story with one or more Scenarios in plain text, using the following format.

Story: transfer from savings to checking account
  As a savings account holder
  I want to transfer money from my savings account to my checking account
  So that I can get cash easily from an ATM

  Scenario: savings account has sufficient funds
    Given my savings account balance is $100
    And my checking account balance is $10
    When I transfer $20 from savings to checking
    Then my savings account balance should be $80
    And my checking account balance should be $30

  Scenario: savings account has insufficient funds
    Given my savings account balance is $50
    And my checking account balance is $10
    When I transfer $60 from savings to checking
    Then my savings account balance should be $50
    And my checking account balance should be $10

Each Given, When and Then is a Step. The Ands are each the same kind as the previous Step. Steps get defined in Ruby like this (detail left out for brevity):

steps_for(:accounts) do
  Given("my $account_type account balance is $amount") do |account_type, amount|
    create_account(account_type, amount)
  end
  When("I transfer $amount from $source_account to $target_account") do |amount, source_account, target_account|
    get_account(source_account).transfer(amount).to(get_account(target_account))
  end
  Then("my $account_type account balance should be $amount") do |account_type, amount|
    get_account(account_type).should have_a_balance_of(amount)
  end
end

Then run the Story like this:

with_steps_for :accounts do
  run 'path/to/file/with/story'
end

Spec Framework

Start with a very simple example that expresses some basic desired behaviour.

# bowling_spec.rb
require 'bowling'

describe Bowling do
  before(:each) do
    @bowling = Bowling.new
  end

  it "should score 0 for gutter game" do
    20.times { @bowling.hit(0) }
    @bowling.score.should == 0
  end
end

Run the example and watch it fail.

$ spec bowling_spec.rb 
./bowling_spec.rb:4:
  uninitialized constant Bowling

Now write just enough code to make it pass.

# bowling.rb
class Bowling
  def hit(pins)
  end

  def score
    0
  end
end

Run the example and bask in the joy that is green.

$ spec bowling_spec.rb --format specdoc

Bowling
- should score 0 for gutter game

Finished in 0.007534 seconds

1 example, 0 failures

Take very small steps

Don’t rush ahead with more code. Instead, add another example and let it guide you to what you have to do next. And don’t forget to take time to refactor your code before it gets messy. You should keep your code clean at every step of the way.

Take the first step now!

$ gem install rspec

(See special installation instructions for Spec::Rails)