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
"woof"
end
def die
@dead = true
end
end
Test::Unit
require 'test/unit'
require 'dog'
class DogTest < Test::Unit::TestCase
def setup
@dog = Dog.new
end
def test_barks
assert_equal "woof", @dog.bark
end
def test_doesnt_bark_when_dead
@dog.die
assert_raises DeadError do
@dog.bark
end
end
end
RSpec
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
Test::Unit output (as full as I could make it)
Ξ code/examples → ruby dog_test.rb --verbose
Loaded suite dog_test
Started
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
Dog
when alive
barks
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'.