I've never been really convinced of the advantages that you get by switching over to RSpec from Test::Unit in Ruby on Rails (despite reading from time to time about RSpec).

What is it about RSpec that most Rails project seems to be using it?

(some code examples clearly indicating advantages of one over the other would be much appreciated)


2 Answers 2


It's largely a matter of taste, and most testing tools worth their salt support both. My personal preference is for RSpec over Test::Unit because a) the output and layout of the tests focusses on what the object under test is supposed to do (as opposed to what the code is) and b) saying 'X should Y' makes more sense to me than 'assert that X predicate Y'.

To give you some context for the points above, here's a (pretty contrived) comparison of the output/source code of two functionally equivalent unit tests, one written using RSpec and the other using Test::Unit.

Code under test

class DeadError < StandardError; end

class Dog
  def bark
    raise DeadError.new "Can't bark when dead" if @dead

  def die
    @dead = true


 require 'test/unit'
  require 'dog'

  class DogTest < Test::Unit::TestCase
    def setup
      @dog = Dog.new

    def test_barks
      assert_equal "woof", @dog.bark    

    def test_doesnt_bark_when_dead
      assert_raises DeadError do


require 'rspec'
require 'dog'

describe Dog do
  before(:all) do
    @dog = Dog.new

  context "when alive" do
    it "barks" do
      @dog.bark.should == "woof"

  context "when dead" do
    before do

    it "raises an error when asked to bark" do
      lambda { @dog.bark }.should raise_error(DeadError)

Test::Unit output (as full as I could make it)

Ξ code/examples → ruby dog_test.rb --verbose
Loaded suite dog_test
test_barks(DogTest): .
test_doesnt_bark_when_dead(DogTest): .

Finished in 0.004937 seconds.

RSpec output (documentation formatter)

Ξ code/examples → rspec -fd dog_spec.rb 

  when alive
  when dead
    raises an error when asked to bark

Finished in 0.00224 seconds
2 examples, 0 failures

2 tests, 2 assertions, 0 failures, 0 errors

P.S. I think Berin (previous responder) is conflating the roles of Cucumber (which grew out of the RSpec project but is independent) and RSpec. Cucumber is a tool for automated acceptance testing in a BDD style, whereas RSpec is a code library for testing which can be, and is, used at unit, integration and functional levels. Hence using RSpec doesn't preclude unit testing - it's just that you call your unit tests 'specs'.

  • 1
    Was not expecting to feel sad when I came here
    – Roman
    Sep 5, 2018 at 21:03

Lately it seems that Cucumber has been getting more support in the Rails community. Here's the nutshell argument I heard from an interview with RSpec's lead (from an old Ruby on Rails Podcast).

In the agile community (at the time) there was a big push for Test Driven Development with the emphasis on testing first to prove you had to change something. There was something philisophically wrong with that. In essence, testing is a way to verify that your implementation is correct, so how do you think differently about the driving design? RSpec's lead surmised that you specify first, and wouldn't it be great if the specification also checked the results of your implementation?

The simple renaming assert to should helps to focus the mind in the correct way to write specifications, and think about design. However, that's only part of the equation.

More importantly, since many TDD beleivers were claiming that the tests documented the design, most documentation was poor at best. Tests are fairly opaque to non-developers unfamiliar with the language. Even then, the design isn't immediately apparent from reading most tests.

So as a secondary goal, RSpec devised a way to generate written documentation from the specifications. It's this written specification that gives RSpec an edge over simple Test::Unit for driving the design of an application. Why write something more than once when you can document and verify design consistency at the same time?

My understanding is that Cucumber, which had the benefit of coming later and learning lessons from RSpec, does a better job of this secondary goal without losing the primary goal (ability to test the implementation from the specification). Cucumber does this with a fairly English like API that non-programmers can reasonably grok. They might need some help from programmers to fill in some definitions of new verification methods, but it's designed to be extensible.

Bottom line is that RSpec/Cucumber shouldn't replace unit testing altogether. They may be better suited to documenting and verifying your design--but there are several implementation tests that still need to be done, particularly with subtle bugs that derive from the implementation and not the design of the application. It does reduce the number of tests you have to write though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.