Ruby標準ライブラリのTest::Unitとgemのtest-unitの違い

Jan 31, 2013  

仕事で Test::Unit を使ってるプロジェクトに guard-test を入れたら挙動が変わった。 原因は guard-test を Gemfile に入れると、gem の Test::Unit が使われるからだった。 Ruby 標準ライブラリの Test::Unit と gem の Test::Unit は挙動が違う。

自分が触った範囲で違うところをまとめる。

assertion メソッドのmessage引数

ここは大きな違い。

  • Ruby標準ライブラリ

    • to_s に反応するものなら何でもOK
  • gemのtest-unit

    • nil String Proc AssertionMessage だけしか受け付けない

出力系

Test::Unit:::UI::Console::TestRunner 辺り

#output

出力の為のメソッド。いろんな所で使われている。 とる引数が違うので、オーバーライドしてると大変。

``` ruby Ruby 標準ライブラリ def output(something, level=NORMAL)


``` ruby gem 版 test-unit
def output(something, color=nil, level=nil)

#add_fault

”…F..F.E.” の、FとかEを表示してる箇所(エラーをスタックしてる箇所)。 標準ライブラリ版は進捗を表示するだけ、gem版はデフォルトで同時にエラーのスタックトレースを表示してる(@show_detail_immediatelyの値によって変わる)。

``` ruby Ruby 標準ライブラリ def add_fault(fault) @faults << fault output_single(fault.single_character_display, PROGRESS_ONLY) @already_outputted = true end


``` ruby gem 版 test-unit
def add_fault(fault)
  @faults << fault
  output_progress(fault.single_character_display, fault_color(fault))
  output_progress_in_detail(fault) if @show_detail_immediately
  @already_outputted = true if fault.critical?
end

#finished

テストが全て終了した後に呼ばれるメソッド。 標準ライブラリ版は全部のエラー情報をここで表示。gem版はデフォルトだと表示しない(@show_detail_immediatelyの値によって変わる)。

``` ruby Ruby 標準ライブラリ def finished(elapsed_time) nl output(“Finished in #{elapsed_time} seconds.“) @faults.each_with_index do |fault, index| nl output(“%3d) %s” % [index + 1, fault.long_display]) end nl output(@result) end


``` ruby gem 版 test-unit
def finished(elapsed_time)
  nl if output?(NORMAL) and !output?(VERBOSE)
  output_faults unless @show_detail_immediately
  nl(PROGRESS_ONLY)
  change_output_level(IMPORTANT_FAULTS_ONLY) do
    output_statistics(elapsed_time)
  end
end

  • gem版はスタックトレースまで表示するけど、shoulda と同時に使っていると shoulda のエラー箇所を表示するので、相性が悪いっぽい。
  • gem版でも --no-show-detail-immediately オプションをつければ @show_detail_immediately の値が false になって 、Ruby版と同じタイミング(テストが全て終わった後)でエラーの表示ができる。