Suite setup and teardown in Test::Unit

Test::Unit does not provide an easy way for suite setup and suite tear down methods to be executed. However, like most things in ruby, if there is a will there is a way. Today we managed to implement them using exit hooks. Before I show you that code, it is important that we understand exactly how Test::Unit works. Here is a simple test:
require 'test/unit'

class ExampleTest < Test::Unit::TestCase
  def test_truth
    puts 'testing truth'
    assert true
  end
end
The part that I am most interested in is the require 'test/unit'. Hidden in the bottom of the code for this class is this code:
at_exit do
  unless $! || Test::Unit.run?
    exit Test::Unit::AutoRunner.run
  end
end
In short, this is the code that allows you to execute your test case rb file and have it actually run the test. This code will be called just before the interpreter exits. To prove to yourself that this is true (don't take my word for it) add this line to your test case anywhere after the require.
at_exit { exit! }
exit! will cause the interpreter to quit while ignoring any exit hooks. Since exit hooks are executed in reverse order of registration, this will effectively short circuit the execution of Test::Unit's exit hook. Now we are getting somewhere. Using what we have just learned, we can now implement suite setup and teardown. Check it out:
require 'test/unit'

class ExampleTest < Test::Unit::TestCase
  def test_one; puts 'one'; end
  def test_two; puts 'two'; end
end

successful = false
at_exit { exit! successful }
at_exit { puts 'suite tear down' }
at_exit do
  unless $! || Test::Unit.run?
    successful = Test::Unit::AutoRunner.run
  end
end
at_exit { puts 'suite setup' }
When you run this, it will print:
suite setup
Loaded suite *the file*
Started
one
.two
.
Finished in 0.000564 seconds.

2 tests, 0 assertions, 0 failures, 0 errors
suite tear down
Enjoy!
blog comments powered by Disqus