tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

失敗のテストのテストの話

何を言っているのか良く分からないかもしれませんが、そういう話。

拙作のTest::Module::Usedとか、もっとメジャーどころだと Test::Pod とか Test::Perl::Critic とか、自前で ok() 相当のメソッドや関数を持っているモジュールがあります。こういうモジュールでは、成功する場合は普通にテストを書けばよいですが、失敗する場合のテストとして、

ok( !someting_ok(), "failure is expected");

みたいな感じのテストは出来ません。テストが失敗すると、本当に失敗しちゃってテストが通らないから。

多分解決策は 2 つあって、

  • パブリックなインターフェースではなく、内部構造をうまく使ってテストする(テスト自体を失敗させない)
  • Test::Builder::Testerを使う

のどちらか、になるかと思います。で、Test::Module::Used の今回のリリース(0.2.1_04)では、後者を使ってテストを書いてみたのだけど、うーん、すごく気持ち悪い。

t/014_requires_ok_fail.t at master from tsucchi's Test-Module-Used - GitHub

#...(最初は省略)
test_out("1..4");
test_out("ok 1 - check required module: Module::Used");
test_out("not ok 2 - check required module: Plack");
test_out("ok 3 - check required module: Test::Module::Used");
test_out("ok 4 - check required module: Test::Class");
$used->requires_ok();


my $builder = Test::Builder->new();
$builder->reset;# reset because plan is automatically set in Test::Module::Used.
plan tests=>1;
test_test(skip_err=>1);

「なんだよ、その builder->reset」とか、「skip_err していいのかい?」とか、いろいろ突っ込みどころはあるのですが、頑張ったけどコレよりうまく書ける気がしません。

plan を自前でセットしている場合、多分 reset するしかないっぽいです。あとはコンストラクタで、plan をセットしないオプションを提供するとか。でも、このモジュールは無駄にオプション多いから、もう増やしたくないし。

err も最初は頑張ってテストしようとしてみたのですが、すごくセンシティブで、全然うまくいかないので、あきらめました。

Test::Builder::Tester はちょっと厳格すぎるところがあるので、もうちょいカジュアルに、「このエラーメッセージが含まれていたらOK」くらいな感じでテストできるといいのになぁ、とか思いました。