Written by: steve ross on February 7th 2007

"rSpec" is my favorite tool du jour. Test Driven Development is all good and it works, but Behavior Driven Development (BDD) seems far more natural to me. What's the difference? As much as anything it's one of attitude. With TDD, you are saying "run this thing and let's see if it's broken." But there is no implicit description about what "this thing" is supposed to do.

With BDD, you are actually spec'ing in executable code. These specs are detailed enough to verify that the code that meets the spec does what you want. Here's an example. Say you are creating a shopping cart. Yes, another frikken shopping cart. Yanking out one part of the functionality of the controller -- the part where you change the quantity of a particular item -- your spec might read, in part:


  describe "Given a request to change quantity, the CartController should" do
      include Stubs
      controller_name "carts"
      integrate_views

      setup do
          Cart.stub!(:new).and_return(stub_cart)
          LineItem.stub!(:find_by_id).and_return(stub_line_item)

          @cart = stub_cart
          @line_item = stub_line_item

          post :change_quantity, {:id => 1, :quantity => 1}
      end

        it "respond w/ success" do
          response.should be_success
        end

        it "assign extension_id" do
          assigns[:extension_id].should == "extension1"
        end

        it "assign line_item" do
          assigns[:line_item].should equal(@line_item)
        end

        it "update the html (using rjs)" do
          controller.should have_rjs(:replace_html,
            'cartstatus',
            /1 item/)
          controller.should have_rjs(:replace_html,
            'cartstatus',
            /\$35\.00/)
        end
  end

You'll have to take my word for it that I created mock objects that describe Cart and LineItem. But, yipee, skipee, when I write the code that makes this come true, I have a cart in which I can change quantity. The point is, if you read this right (or run the specdoc task), you get something along these lines:


Given a request to change quantity, the CartController should

- respond w/ success
- assign extension_id
- assign line_item
- update the html (using rjs)

Now that's a plain English version of the same thing. Pretty cool, huh?

POSTSCRIPT: Since this post was written, much water has passed under the bridge. The rSpec Book is now out, mocking and stubbing have changed somewhat, and a number of matchers have changed.