Version 4, last updated by Vitalie Lazu at June 17, 2010 16:30 UTC

What is RSpec?

RSpec is a tool for describing behavior of a system. It is written in Ruby, taking advantage of Domain Specific Language (DSL) capabilities Ruby provides. As a result it is very expressive. “Getting the words right” is the goal of the creators of RSpec. Specs (tests) read like English sentences:

describe SomeController, 'some_action' do
  it 'should render template some_template' do
    get :some_action
    response.should render_template('some_template')
  end

  it 'should fetch some records and make them available to the view' do
    get :some_action
    assigns[:records].should_not be_empty # @records should not be empty.
  end
end

As you can see the comment in the second example (the construct beginning with it) is an overkill. The message is communicated in executable code!

The above examples actually use RSpec extension (plugin called rspec-rails) designed to describe Rails code. When it comes to Rails development, rspec and rspec-rails gems (or plugins) are used together.

Installation

It is a two-step process. First install rspec-rails gem (rspec is dependency for rspec-rails, so you should be getting that automatically, but if you don’t, simply install rspec and then rspec-rails):

sudo gem install rspec-rails

After you’ve done that run the rspec generator in the root of your Rails project which will create the infrastructure needed to use RSpec in the project (this is already done for Breakout).

ruby script/generate rspec

That’s it, you can now start writing specifications (specs for short) describing the code.

Usage

RSpec is a Behavior Driven Development practice. So you should start with specification and no code and let the expected behavior drive out the code. Advantages of this are:

  • you write only the code you actually need, no more, no less,
  • you actually use the various objects before they are even there, this leads to clear API,
  • you are concentrating on one small problem at a time.

The red-green-refactor cycle has been carried over from test/unit. After all rspec is built on test/unit core. This means you make an example pass, then you can refactor the implementation code, make sure the spec still passes, and move on to the next example.

All specs should be placed in spec/ directory or subdirectories (which mirror the rails directory hierarchy, for example controller specs are found in spec/controllers/, while views in spec/views/. The naming convention is this:

things_controller_spec.rb
my_template.rhtml_spec.rb
model_spec.rb

You also have to add this line to each spec file:

require 'spec_helper'

If you follow this convention, then to run the whole test suite you have to type

rake spec

Or you can run a particular spec with

ruby script/spec spec/controllers/things_controller_spec.rb

Or you can run it with system-wide rspec (if you have rspec and rspec-rails gems installed):
running specs with system-wide rspec can help if you have some weird problems with script/spec one.
and sometimes it can reveal some hidden problems in your specs, as its usually runs specs in different order from script/spec

spec spec/controllers/things_controller_spec.rb
# spec usually resides in /usr/bin/, but it may vary

Resources

More comming soon…