TDD/BDD Rails Cucumber / RSpec duplication

It might be of use to look into the screencasts at BDDCasts.com. They walk you through creating the stories and specs for an app. It really helped me. Also own the rspec book, but was still confused. You might even want to just check out their source on github.

For me it goes like this:

  • Cucumber to test what the user will see. (Full stack test)

  • Rspec to test everything else. (Model, controller)


Rspec and Cucumber are independent and you can use Cucumber and another test framework for your tests (Test Unit, shoulda etc).

The point is, what do you want to test with cucumber? Because indeed you could end duplicating tests and that would not be really useful isn't it? :)

There are different philosophies with Cucumber.

With Cucumber you can do:

DMA (direct model access meaning, Yes you can fully test your model like you would do in rspec)

Simulated browzer (access entire MVC stack, no javascript)

Automated browser (use webrat and selenium to access your views, with javascript, slower, real browzer)

What I like to do is use cucumber to check what is returned to the user. This is usually what makes sense to me when I define my stories since I don't have really in mind the code I am going to write. So I am testing the final result with Cucumber -> views (using simulated or automated browzer)

Then I use rspec to test any code I write in the controllers and models.

Thus in your case,

When a user enters an invalid telephone number then they get a message saying "Invalid Telephone Number"

I would use Webrat to check that the user get the Invalid Telephone Number message in the view. I would use Rspec to test my controller action and model.


Cucumber is used to explain (make a description) of a part (story) of the application rather than unit tests or behaviour tests (which is the focus of RSpec)

So, IMHO Cucumber tests (stories) do not substitute for RSpec tests.

The RSpec tests tend to drive development of the models and controllers, and the stories tend to drive development of the views.

From your description it seems like you are using cucumber to both test the stories and the behavior.


Think of Cucumber as testing your whole application, from the outside in, where RSpec is unit testing of specific modules. You start out by specifying what behaviors you want your application to have in Cucumber then drop down into RSpec and describe the classes and modules that make that behavior work.

It's taken me a while to kind of get it but I'm finding Cucumber is really good for describing in broad terms what features you want your application to do and RSpec is really good at describing how it should actually do it.

So you would say in your cucumber stories what kind of feature you want and write super simple steps to provide input and look at output. Then you drop down to RSpec and write specifications on how it should actually do it.

Let's say your feature is the ability to search for user names on a website. You might write a cucumber feature and the first (and only the first) scenario like this:

Feature: Search users
  In order to find people with similar interests as myself
  As a user
  I want to search for people

Scenario: Search for similar hobbies
  Given there is a search page
    And there is a list of hobbies
    And one of the hobbies is "full contact ironing"
   When I select "full contact ironing"
    And press search
   Then a list of users with the hobby "full contact ironing" are shown

You run Cucumber, it tells you the steps you're missing, you copy those and create the simple steps to check for this stuff but don't write any code yet.

When you're done with your step definitions you drop down into RSpec and start writing specifications on how you want this to work. (Cucumber of course should be failing)

describe "SearchController" do

  it "should respond to searches" do
    sc = SearchController.new
    sc.should respond_to(:search)
  end

end

You run RSpec and watch it fail then go off and write your code:

class SearchController

  def search
  end

end

That's it. Now run your test again. It should pass so start getting more specific and start describing how you will actually use the search feature. I didn't want to get too in depth into it I just wanted to give you the idea that you describe what you want in Cucumber then describe how it should actually work in RSpec.

Of course you can do everything in Cucumber or everything in RSpec but I've really found Cucumber helps me say in very simple ways what I want where if I try to do that in RSpec I get bogged down in the details. If I use Cucumber first to describe the basic feature I want and why then I can drop into RSpec and say how I want the feature to actually work.

There will be duplication in your tests sometimes, which isn't very DRY, but if you think of it as a level of detail issue it might not bother you as much. I was doing a lot of duplication of effort at first till I realized I should just say generally what I want in Cucumber then say specifically what I want in RSpec.

This is all just one newbie's idea of how to use the tools but it's seeming to work well for me so far. I've probably given you a horrible example but I'm just trying to get the point across of the general detail to specific detail I've found useful when using the tools.