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などと余計なものをなんで実行しようとしてるんだ...うーん...わからん。