Respect RSpec

Over the past week and a half, I've been busting my ass trying to learn the ropes of Behavior-Driven Development with RSpec. I had been interested in learning either Test-Driven Development or Behavior-Driven Development for quite a while, so I just jumped on one of the two and test the waters out for a while.

I've been reading a lot on TDD and BDD for the past couple of months, yet never took the time to implement it to my current projects. The main reason is because I thought it would take me too much time to learn and would bog me down too much, when all I wanted was a workable application running as soon as possible. But, an opportunity presented itself (more on that in the future), so I chose the development technique that seemed better for me: BDD.

Reading about RSpec through other blogs on the Internet, it just seemed so intuitive to use that for testing, I kinda thought it was too good to be true. So after installing RSpec and getting it running on my application, I realized it was true after all. It's ridiculously easy to write your own tests with RSpec, and it's almost plain English (just like good ol' Ruby). It includes built-in stubs and mocks to simulate parts of code, so you can even drop fixtures if you want (although admittedly, a lot of the shortcomings fixtures had were fixed with Rails 2.0). In fact, here's a simple controller test:

describe ProductsController do
before(:each) do
@product = mock_model(Product, :to_param => "1")
Product.stub!(:find).and_return(@product)
end
it "should call the action successfully" do
get :show, :id => "1"
response.should be_success
end
it "should find the product" do
Product.should_receive(:find).with("1").and_return(@product)
get :show, :id => "1"
end
it "should assign the found product for the view" do
get :show, :id => "1"
assigns[:product].should eql(@product)
end
end

This test actually works for testing the show action in a controller. I wrote this just to show how readable the code is. I never knew testing would be so readable! And like I said, once you wrap your head around mocks and stubs, it's ridiculously easy to implement. As a great bonus, RSpec can also integrate with rcov, a tool that actually checks what parts of your code are tested. It's a great tool for making sure you achieve 100% coverage of your code.

Unfortunately, I didn't actually do any BDD this time around, as I already had a good chunk of my application up and running already. But now that I have discovered the joys of RSpec, all my upcoming products will be fully done using BDD techniques: I won't write a line of code until I write the behavioural test before.

A couple of ceveats, though. Hey, nothing's perfect! First off, if you use different types of plugins for your application, you'll find some parts of it difficult to test in RSpec. Most plugins use the Ruby's own Test::Unit testing framework to test their own functionality, but parts in your code where you use these plugins can get you the first time around. Also, if you're like me, and already have written code for your app, you'll start finding different ways to fix your code to conform to RSpec testing. This isn't necessarily a bad thing, as this is most likely a warning sign that you need to refactor that piece of your code anyway. But it's takes a bit of your time away, so be prepared for this.

In short, RSpec is so easy to use, I don't see why people shouldn't use it in their own projects. I suggest every Rails developer should look into RSpec (or any other testing method, really) and stop being lazy. I know I was, but never more!

RSpec References

Ryan Bates from Railscasts has a great screencast that can serve as an intro to testing controllers. And the best part is that it's free!

Geoffrey Grosenbach over at PeepCode has an excellent three-part series on RSpec, with about three hours of RSpec goodness! No, they're not free, but the $9.00 per episode is truly worth it. This was my secret weapon in learning RSpec in less than two weeks - The best 27 bucks I've spent in my software development career!