From: Phlip Date: 2008-02-17T02:19:50+09:00 Subject: Re: Test::Unit maintainer Berger, Daniel wrote: > I have a few feature requests: > > First, a skip method that I can use within the test cases, along the > ability to specify the reason why, and are reported in the final output > as "skipped". Hmm. The test zealots around here (such as me) will tell you if a test fails you should revert your code and try again. However, those with real-world experience (such as me), will also tell you that skipping tests is a fact of life - especially as your test KLOC exceeds the 5s... > Second, a startup and shutdown method that only run once per test case > (as opposed to once per test). Handy for database connections and the > like. And those same test zealots will demand better "test isolation". Expensive setup is a "design smell", and an opportunity to use mock systems like Mocha. That said, here's a brute-force attempt at your patches, from 1.9, with apologies and excuses below it! def suite_setup p "doin' somethin' heavy!" end def suite_teardown p "hide it before they catch us" end def test_skipme skip 'my foot\'s asleep' assert false, 'yet we pass' end ... module Test module Unit class TestCase class Skipped < Exception def initialize(why); @why = why; end attr_reader :why end def skip(why) raise Skipped.new(why) end def run(result) yield(STARTED, name) @_result = result begin setup __send__(@method_name) rescue Skipped => e print '-skipped:' print e.why rescue AssertionFailedError => e add_failure(e.message, e.backtrace) rescue Exception raise if PASSTHROUGH_EXCEPTIONS.include? $!.class add_error($!) ensure begin teardown rescue AssertionFailedError => e add_failure(e.message, e.backtrace) rescue Exception raise if PASSTHROUGH_EXCEPTIONS.include? $!.class add_error($!) end end result.add_run yield(FINISHED, name) end end end end module Test module Unit class TestSuite def run(result, &progress_block) yield(STARTED, name) a_case = @tests.first a_case.suite_setup if a_case and a_case.respond_to?(:suite_setup) @tests.each do |test| test.run(result, &progress_block) end ensure a_case.suite_teardown if a_case and a_case.respond_to?(:suite_teardown) yield(FINISHED, name) end end end end Those monkey-patches went a bit long. (If you simply must use them, paste them into the equivalent of your test_helper.rb!) The first one is long because def run(result) has to be long. Short monkey-patches, like any kind of incremental changes, are naturally much safer than long ones at upgrade time. It appears that def run(result) must be long because (correct me whether or not I'm wrong) Ruby will not allow us to refactor a long chain of typed 'rescue' lines into some cute pattern. ( Maybe we can .curry them! ;-) So there's your first two requests. And note that they might indeed be hard to gemify, if they must cohere so strongly with the exact center of RubyUnit! -- Phlip http://flea.sourceforge.net/PiglegToo_1.html