hudsonでテスト結果集計したいので、junit形式の結果出力するテストランナー

hudsonでテスト結果集計したいので、junit形式の結果出力するテストランナー
あるのかなぁとおもったんだけど、パッとみつけられず。

cucumberにはjunit形式で出力するオプションがあるようなんだけど、、、

Customizing the Ruby TestRunner « End of Line
http://endofline.wordpress.com/2008/02/11/a-custom-testrunner-to-scratch-an-itch/

これと、python用のxmlrunnerを参考にして作ってみた。

試してみたいことはあるんだけど、とりあえずはこと足りたので、
まずはここまで。

# Usage:
#   ruby -rjunitrunner [test] --runner=junitrunner
#require 'test/unit/ui/testrunnermediator'
#require 'test/unit/ui/testrunnerutilities'

require 'test/unit'
require 'test/unit/ui/console/testrunner'

class JunitRunner < Test::Unit::UI::Console::TestRunner


  # Begins the test run.
  def start
    setup_mediator
    attach_to_mediator
    return start_mediator
  end


  # set suite name
  @g_suite_name
  # calc time
  @g_test_start_time
  @g_time_array
  private
  def setup_mediator
    @mediator = create_mediator(@suite)
    suite_name = @suite.to_s
    @g_suite_name=suite_name
    if ( @suite.kind_of?(Module) )
      suite_name = @suite.name
    end
    output("<?xml version=\"1.0\" encoding=\"utf-8\"?>")

  end

  def start_mediator
    return @mediator.run_suite
  end

  def add_fault(fault)
    @faults << fault
    #@already_outputted = true
  end

  def started(result)
    @result = result
  end



  def finished(elapsed_time)
    output("<testsuite errors=\"#{@result.assertion_count}\"
failures=\"#{@result.failure_count}\" name=\"#{@g_suite_name}\"
tests=\"#{@result.run_count}\" time=\"#{elapsed_time}\">")
    ts = @suite.tests[0]
    fcount = 0
    e = ts.tests.size - 1
    for i in 0 .. e
      tr = ts.tests[i]
      tname =  tr.name
      fname=nil
      fname = @faults[fcount].test_name if @faults.length > 0
      et = @g_time_array[i]
      output("<testcase classname=\"#{@g_suite_name}\" name=\"#{tname}\"
time=\"#{et}\">")
      if fname != nil and tname == fname then
        fault = @faults[fcount]
        fcount = fcount + 1
        output("<failure type=\"exceptions.AssertionError\"><![CDATA[")
        output("#{fault.long_display}")
        output("]]></failure>")
      end
      output("</testcase>")
    end
    output("  <system-out><![CDATA[]]></system-out>")
    output("  <system-err><![CDATA[]]></system-err>")
    output("</testsuite>")

  end


  def test_started(name)
    @g_test_start_time = Time.now
  end

  def test_finished(name)
    elapse_time = Time.now - @g_test_start_time
    if @g_time_array  == nil then
      @g_time_array = []
    end

    @g_time_array << elapse_time
    @already_outputted = false
  end

end


Test::Unit::AutoRunner::RUNNERS[:junitrunner] = proc do |r|
  JunitRunner
end