7.2. Ruby's
Test::Unit
Ruby uses a testing framework known as
Test::Unit (sometimes referred to as test/unit) to run your application's tests.
Test::Unit is similar to the xUnit frameworks
that you find in other programming languages, and implements four
major concepts:
-
An assertion is
a single line of code that evaluates an expression and tests the
results against an expected value. For example, you might assert
that a password is at least six characters long; failing an
assertion fails the associated test.
-
A test is a
method, whose name begins with test_, that contains a
number of related assertions that, taken together, test one small piece of
your application. For example,
test_for_disallowed_passwords might contain assertions
that verify that bad passwords are rejected (such as a password
that is too short, contains all spaces, or is the word
"password").
-
A test case
class is a subclass of Test::Unit::TestCase that contains
a collection of test methods designed to test a functional area of
your application. For our photo share application, we might have a
test case class that tests everything having to do with
categories.
-
A test suite is
a collection of test cases. When you run a test suite, it executes
the tests in each test case that it contains. You won't need to use
this with Rails applications, because Rails handles the task of
running all your test cases.
Suppose you have the following non-Rails
class:
class BasicNumber
def initialize( number )
@value = number
end
def add( x )
@value + x
end
def multiply( x )
@value * x
end
end
Here is an example of a set of tests for this
class:
require "basic_number.rb"
require "test/unit"
class TestBasicNumber < Test::Unit::TestCase
def test_basic_add
num = BasicNumber.new(16)
assert_equal(20, num.add(4) )
assert_equal(0, num.add(-16) )
# this test will fail, to show what happens on failure
assert_equal(100, num.add(99), "Adding 99 doesn't work")
end
def test_basic_multiply
num = BasicNumber.new(16)
assert_equal(32, num.multiply(2) )
assert_equal(8, num.multiply(0.5) )
end
end
When you run this test file, it produces this
output:
>ruby test_basic_number.rb
Loaded suite test_basic_number
Started
F.
Finished in 0.015 seconds.
1) Failure:
test_basic_add(TestBasicNumber) [test_basic_number.rb:11]:
Adding 99 doesn't work.
<100> expected but was
<115>.
2 tests, 5 assertions, 1 failures, 0 errors
When you run the test class, it automatically
runs all the tests. You don't need to explicitly call a test runner
or create a test suite. Just subclassing
Test::Unit::TestCase and running the file causes the tests
to be executed.
Test::Unit provides a large number of
assertions you can use, and
"#rubyrails-chp-7-table-1">Table 7-1 shows the main ones. Most
assert methods take an optional message parameter. If a message is
included, then that message is displayed if its assertion
fails.
Table 7-1. Commonly used assertions
|
Assertion
|
Description
|
|
assert( boolean, [msg] )
|
Passes if boolean is true
|
|
assert_equal( expected, actual, [msg] )
assert_not_equal( expected, actual, [msg]
)
|
Passes if expected == actual
|
|
assert_match( pattern, string, [msg] )
assert_no_match( pattern, string, [msg]
)
|
Passes if string =~ pattern
|
|
assert_nil( object, [msg] )
assert_not_nil( object, [msg] )
|
Passes if object == nil
|
|
assert_instance_of( class, object, [msg]
)
assert_kind_of( class, object, [msg] )
|
Passes if object.class == class
Passes if object.kind_of?(class)
|
|
assert_raise( Exception, ... ) {block}
assert_nothing_raised( Exception, ...)
{block}
|
Passes if the block raises (or doesn't) one of
the listed exceptions
|
You can define two special methods in your test
case class: setup and teardown. Just before each
test method is executed, setup is called to allow you to
set up the environment for the test (open a database connection,
load test data, and so on). Likewise, immediately after each test
method returns, teardown is called to clean up and release
any resources acquired by setup.
 |