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.

require 'rspec'
require 'dog'
describe Dog do
before(:all) do
@dog = Dog.new
end
context "when alive" do
it "barks" do
@dog.bark.should == "woof"
end
end
context "when dead" do
before do
@dog.die
end
it "raises an error when asked to bark" do
lambda { @dog.bark }.should raise_error(DeadError)
end
end
end

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'.

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.