Railsの自動テスト環境

Autotest::Screenが便利だと聞いて以下の記事参考に導入
http://saikyoline.jp/weblog/2007/07/autotestscreen.html
http://saikyoline.jp/weblog/2007/09/autotest.html
http://saikyoline.jp/weblog/2007/09/autotest_1.html

インストール

% gem install ZenTest

設定とか

http://saikyoline.jp/weblog/2007/07/autotestscreen.html
に書いてある、

ZenTest (3.6.0)のものは結果をうまく拾えていないようだったので

という点は最新(3.9.1)でも治ってない。
Ctrl-C2回押して終了しない問題も治ってない。
というわけでyoshukiさんに感謝しつつ$HOME/.autotestに以下を記述

require 'autotest/screen'
# Ctrl-C*2で終了しない件の暫定対応
Autotest::HOOKS.delete(:interrupt)
# screenでの表示改善
Autotest::Screen.statusline = %q[%{=r dd} %-w%{=b dd}[%n] %t %{-}%+w %=]

class Autotest::Screen
  Autotest.add_hook :run_command do |at|
    message 'Testing...' if execute?
  end

  Autotest.add_hook :ran_command do |at|
    if execute? then
      output = at.results.join
      failed = output.scan(/^\s+\d+\) (Failure|Error):\n(.*?)\((.*?)\)/)
      if failed.size == 0 then
        message "All Green", :green
      else
        f,e = failed.partition { |s| s[0] =~ /Failure/ }
        message "Red F:#{f.size} E:#{e.size}", :red
      end
    end
  end
end

で、動作するようになったんだけど、特定のテストメソッドを修正して保存したとき、
例えばuser_test.rbのtest_createメソッドを修正して保存すると...

/usr/bin/ruby1.8 -I.:lib:test test/unit/user_test.rb -n "/^(test_create)$/" | unit_diff -u
/usr/lib/ruby/1.8/test/unit/autorunner.rb:138:in `=~': can't convert Symbol into String (TypeError)
        from /usr/lib/ruby/1.8/test/unit/autorunner.rb:138:in `options'
        from /usr/lib/ruby/1.8/test/unit/collector.rb:26:in `[]'
        from /usr/lib/ruby/1.8/test/unit/collector.rb:26:in `include?'
        from /usr/lib/ruby/1.8/test/unit/collector.rb:25:in `each'
        from /usr/lib/ruby/1.8/test/unit/collector.rb:25:in `include?'
        from /usr/lib/ruby/1.8/test/unit/collector.rb:18:in `add_suite'
        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/inflector.rb:257:in `find_all'
        from /usr/lib/ruby/1.8/test/unit/collector.rb:18:in `each'
         ... 7 levels...
        from /usr/lib/ruby/1.8/test/unit/autorunner.rb:198:in `run'
        from /usr/lib/ruby/1.8/test/unit/autorunner.rb:13:in `run'
        from /usr/lib/ruby/1.8/test/unit.rb:278
        from test/unit/user_test.rb:5

などとなって失敗する場合と

/usr/bin/ruby1.8 -I.:lib:test -rtest/unit -e "%w[test/unit/user_test.rb].each { |f| require f }" | unit_diff -u
Loaded suite -e
Started
.
Finished in 0.393934 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

となって成功する場合がある...

/usr/bin/ruby1.8 -I.:lib:test test/unit/user_test.rb -n "/^(test_create)$/" | unit_diff -u

じゃなくて

/usr/bin/ruby1.8 -I.:lib:test test/unit/user_test.rb -n "test_create" | unit_diff -u

だったら成功する。

少しおいかけてみると
/usr/lib/ruby/1.8/test/unit/autorunner.rb:138が

132           o.on('-n', '--name=NAME', String,
133                "Runs tests matching NAME.",
134                "(patterns may be used).") do |n|
135             n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n)
136             case n
137             when Regexp
138               @filters << proc{|t| n =~ t.method_name ? true : nil}
139             else
140               @filters << proc{|t| n == t.method_name ? true : nil}
141             end
142           end

となってて、debuggerしかけて確認すると138行目は2回通ってて、それぞれのtの値は以下のようになっていた。

(rdb:1) p t
#<UserTest:0xb78617f0 @method_name="test_create", @test_passed=true>
(rdb:1) p t
#<ActionMailer::TestCase:0xb781a738 @method_name=:default_test, @test_passed=true>

t.method_nameに:default_testというシンボルが入ってきている時に失敗しているようだ。
:default_testなどと余計なものをなんで実行しようとしてるんだ...うーん...わからん。