Test::More で no_plan が良くない訳
Test::More 自動試験をさらに便利にする - Perl入門〜サンプルコードによるPerl入門〜
no_planは、「テストを弱くするのでなるべく避けてください」とドキュメントにあるのですが、何が弱くなるのかよくわからない。
オイラも結構 no_plan 使ってしまうのだけどね、でもホントは良くないんだよね。exit されると、テストが途中で終了しちゃうんだよね。例を作るとこんな感じ。
#!/usr/bin/perl use strict; use warnings; use Test::More "no_plan"; # 以下テスト is( sum(1,2), 3);# => ok is( sum('a', 0), -1); #=> ホントは NG だけど、exit されて上が ok だからテストスイートが通ってしまう # これがテストされる関数。同一ファイル・パッケージにおいてるけど、 # 別ファイル・別パッケージにあると考えたほうが問題を認識しやすいと思う。 sub sum { my( $a, $b ) = @_; if ( $a !~ /\d+/ || $b !~ /\d+/ ) { #正数しかだめとする warn "invalid argument!\n"; exit 0; #お作法としては、die するほうがいいけど、あえて exit } return $a + $b; }
こんな感じで、意図せずテストが通ってしまいます。(↓)
% prove a.pl a.pl .. 1/? invalid argument! a.pl .. ok All tests successful. Files=1, Tests=1, 1 wallclock secs ( 0.08 usr 0.06 sys + 0.22 cusr 0.06 csys = 0.42 CPU) Result: PASS
Test::More 自動試験をさらに便利にする - Perl入門〜サンプルコードによるPerl入門〜(コメントより)
テストの分岐ミスやexit 0 というのは、実際にどのような状況で起こるのでしょうか?
そういった経験って今までありますでしょうか?
僕の経験ではこの「exit」を2回くらいました。どちらも結構典型的なケースだと思います。
- 他人から引き継いだプログラム
- CGI で使っているライブラリのテストコードを書いているとき
1. は他人から引き継いだプログラムにテストコードが無くて、新たに自分で書いているときにハマりました。そのころは exit がテストコードを終了させることを知らなくて、かなり焦りました。
2. はたぶん最も典型的なケース。CGI だと、die すると Internal Server Error になってしまうので、エラー終了も exit を使うことが多いと思います。CGI が use しているライブラリをテストコードでも使っていると、(とくに意図せずエラーになったときに)exit されてハマることがあります。
どちらも結局原因を特定してからは力技で押し切ったのだけどね。。。1は exit を書き換え。2はテストコードでは exit しているサブルーチンを動的に書き換えて逃げました。
about Test::More::done_testing - TokuLog 改めB日記
Test::More::done_testing が導入されているわけですが、みなさんつかってますか?
と、最近の Test::More だと no_plan の代わりにテストの末尾に done_testing を書けるらしいので、これが使えるとありがたのですが。。。Perl 5.8.8 あたりだと、0.62 くらいの古いやつがバンドルされているみたいで、今の環境では使えないんだよなぁ。自分でモジュール入れる権限があれば良いのですが、今の開発環境は無いんだよねorz
done_testing が使えれば使う、テストの数があんまり増減しないなら tests をちゃんと書く、no_plan なら exit をケアする、というのが無難ながら結論になるのかなぁ。