Skip to content

Using Logging and Test::Unit together

If you use Tim Pease’s ruby Logging library in conjunction with Test::Unit, you must make sure to require ‘logging’ before you require ‘test/unit’. Both Logging and Test::Unit make use of Ruby’s at_exit method hook: Logging uses it to close any appenders (e.g. if you are writing a log to a file, it closes the file), and Test::Unit uses it to actually run the unit tests. Ruby executes any at_exit methods in reverse order, so if you require ‘logging’ after you require ‘test/unit’ then your logs are closed before the unit tests are run. If you try to log anything in the code you are testing, you’ll get an error like this:

  1) Error:
test_at_exit_conflict(AtExitConflictTest):
RuntimeError: appender '<Logging::Appenders::Stdout: stdout>' is closed
method append in appender.rb at line 107
method log_event in logger.rb at line 366
method each in logger.rb at line 366
method log_event in logger.rb at line 366
method debug in (eval) at line 6
method test_at_exit_conflict in logging-testunit-atexit.rb at line 11

This code will throw the above exception:

require "test/unit"
require "logging"

$log = Logging::Logger["testlogger"]
$log.add_appenders(Logging::Appender.stdout)

class AtExitConflictTest < Test::Unit::TestCase
  def test_at_exit_conflict
    $log.debug("test")
    assert(true)
  end
end

Reverse the order of the require ‘test/unit’ and require ‘logging’ to solve the problem.

Post a Comment

Your email is never published nor shared. Required fields are marked *