Logo Devoh

First Thoughts on RSpec

For the Amazon FPS API I'm working on right now, I've decided to try out the BDD approach and write behaviors instead of tests.

Let me first say that I'm not an expert on testing by any means, and while I have a pretty good grasp on the how and the why behind it, I've been somewhat slack in the practical application of the philosophy. Case in point: I wrote the majority of the code for the API before writing a single line of tests.

That being said, I installed the RSpec gem earlier this week and began playing around with some tests for a new class I was working on. The class is used to represent a URL query, and is basically just a simplified hash with a special #to_s.

Here's an excerpt from the spec:

describe 'A query' do
  before(:each) do
    @url = 'http://example.com/'
    @query = Amazon::FPS::Query.new
  end

  it 'should be accessible as an array' do
    @query[:amount] = 10
    @query[:amount].should == 10
  end

  it 'should convert keys to symbols' do
    @query['symbol'] = 'aleph'
    @query[:symbol].should == 'aleph'
  end
end

It should be pretty clear what's happening here. We're defining a set of behaviors for "a query", and we want to make sure that "a query should be accessible as an array," and a "a query should convert keys to symbols." The before block gets execute before :each behavior, just as setup would within Test::Unit.

While there's truly beauty in the DSL at work here, even it doesn't compare to the beauty of being able to generate a specifications list from your behaviors:

A query
- should be accessible as an array
- should convert keys to symbols
- should convert to a query string
- should convert parameters to strings
- should sort its parameters
- should encode its parameter values
- should be instantiable with a hash

Overall I've been fairly impressed with the ease of use of RSpec. It provides a very simple structure to allow you to clearly define the expected behavior of your application, and makes verifying that behavior a trivial endeavor. I haven't had a chance to explore all of its matchers yet, but there definitely seems to be a lot of power and flexibility to be garnered there.