Short question: if I have a test that iterates over a list of items, how
can I get assertion failure messages and exceptions to report which
iteraation I am on?
Longer question:
Suppose I have a test like this:
require ‘test/unit’
def f(x)
return x**2
end
class MyTest < Test::Unit::TestCase
def initialize(*args)
super(*args)
p *args
end
def test_x_squared
assert_equal 1, f(1)
assert_equal 4, f(2)
assert_equal 9, f(3)
end
end
I can rewrite test_x_squared like this:
def test_x_squared
for i in 1..3 do
assert_equal i*i, f(i)
end
end
but if the test fails (I rewrite f(x) to return x**4), I get:
"test_x_squared"
Loaded suite test
Started…
…
Failure occurred in test_x_squared(MyTest) [test.rb:21]: Expected <4> but was <16>
which isn’t very helpful. If f(x) raises an exception, the message is
also not very helpful:
"test_x_squared"
Loaded suite test
Started…
…
Error occurred in test_x_squared(MyTest): RuntimeError: f(x) failed
test.rb:4:in f' test.rb:22:in
test_x_squared’
test.rb:21:in each' test.rb:21:in
test_x_squared’
test.rb:20
The solution I came up with is something like this:
def test_x_squared
for i in 1..3 do
appendage = "while testing for i=#{i}"
begin
assert_equal i*i, f(i), appendage
ensure
$!.message.replace($!.message + ' ' + appendage) if $!
end
end
end
but it seems like there should be a cleaner or more generic solution
than this. What is it?
Thanks,
Paul