本質的でないところではまった話
railsでスペックを書くのが楽しくなってきた頃、そろそろテストを自動化したいな、と思いまして、以前第25回 Ruby/Rails勉強会@関西, スはスペックのス〜RSpec(関西弁)の動画 - 角谷HTML化計画(2008-04-12)を見ていて、そういえばテストの自動化ツールあったよな、ということでZenTest(の中のautotest)を導入し、このへんやこのへんを参照するなどしてAutotest::Screenを使った環境を整えました。
ところが、なぜかテストが失敗しても「All Green」の表示。どうもフックが正常に機能していない様子。これらの記事がかかれた当初は動いたのでしょうが、ZenTest3.10.0ではだめでした。
まあそこからあらゆるソースを追うこと3時間、出した結論(~/.autotest)がこちらです。
require 'autotest/screen' Autotest::HOOKS.delete(:interrupt) Autotest::Screen.statusline = "%-w%{=b bw}%n %t%{-}%+w %u %= %m/%d %D %c" class Autotest::Screen SCREEN_COLOR[:green] = 'gw' SCREEN_COLOR[:yellow] = 'yk' Autotest.add_hook :run_command do |at| message 'Running' if execute? end Autotest::HOOKS[:ran_command] = [ lambda do |at| next unless execute? results = [at.results].flatten.join("\n") output = results.slice(/(\d+)\sexamples?,\s*(\d+)\s.*failures?(?:,\s*(\d+)\s.*pendings?)?/) if output ex,fail,pend = $~.captures.map {|e| e.to_i} if 0 < fail message "FAIL #{ex}ex, F:#{fail} ", :red elsif 0 < pend message "Pend #{ ex}ex, F:#{fail} P:#{pend}", :yellow else message "All Green #{ex}ex", :green end end end ] end
要するにこのバージョンのautotestのフックのしくみ(pluginと呼ばれている)は、登録されているフックメソッドをEnumerable#any?を使って実行していくため、途中で真を返すと後から登録されたフックは無視されてしまうという仕様なので、後からAutotest.add_hookで登録しても、既に登録してあるオリジナルのフックメソッドに阻まれてしまうということのようです。仕方ないので、Autotest::HOOKS[:ran_command]に直接フックメソッドの配列を上書きしてしまったというわけです。
今日も莫大な時間をこのような本質的でないことに費やされましたが、こういうことを通じてこそrubyの基礎技術が着々と身につけられているので、仕方ないね。