読者です 読者をやめる 読者になる 読者になる

Ruby1.8でも1.9でも動くTest::Unit用テストランナーを作る

はじめに

Rubyユニットテストを行うフレームワークはいろいろありますが、とりあえず手っ取り早いのは標準添付のtest/unitだったりします。しかし、Ruby1.9以降のTest::Unitは1.8に添付されているものとは別モノ*1のため、1.8用のテストランナーはそのままでは1.9で使えなかったりします。
Ruby1.8にも1.9にも対応したいライブラリを書いてる人にとってはこれは結構不便なので、どっちでも使えるテストランナーを考えてみました。

コード

Test::Unitのテストランナーは

を使用するようになっています。
そこで、Test::Unitのメソッドを調べてsetup_argvがあったら(=1.9なら)setup_argvを使うように、そうでなくてAutoRunnerがあったら(=1.8なら)AutoRunner.runを使うようにしてみました。
ちなみに、1.9用のほうはRuby1.9.2のテストからそのまま頂いてきたものです。

#!/usr/bin/env ruby
require 'test/unit'

if Test::Unit.methods.include? :setup_argv
  # Ruby1.9Ruby1.9.2-p136のソースコードのtest/runner.rbから拝借
  src_testdir = File.dirname(File.expand_path(__FILE__))
  srcdir = File.dirname(src_testdir)
  Test::Unit.setup_argv {|files|
    if files.empty?
      [src_testdir]
    else
      files.map {|f|
        if File.exist? "#{src_testdir}/#{f}"
          "#{src_testdir}/#{f}"
        elsif File.exist? "#{srcdir}/#{f}"
          "#{srcdir}/#{f}"
        elsif File.exist? f
          f
        else
          raise ArgumentError, "not found: #{f}"
        end
      }
    end
  }
elsif Test::Unit.constants.include? 'AutoRunner'
  # Ruby1.8用
  Test::Unit::AutoRunner.run(true, './')
else
  raise Error, 'Test runner not found'
end

これをrunner.rbみたいなファイル名で保存し、テストを実行してみると…
f:id:ser1zw:20110112234052p:image
Ruby1.8.7, 1.9.2のどちらでもユニットテストができました。すばらしい!

*1:minitest/unitを使って再実装されたもので、完全な互換性は無いらしいです