From: Paul Brannan Date: 2003-01-11T01:29:31+09:00 Subject: iterating in a test 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