モダンPerlの世界へようこそ

第28回 Test::More:no_planからdone_testingへ

この記事を読むのに必要な時間:およそ 5 分

done_testing

このような問題点を改善するため,2009年3月にリリースされたTest::More 0.87_01からはdone_testingという新しいテストコマンドが追加されました。これは要するにTest Anything Protocolの宣言部を自分の指定した場所に出力するためのコマンドで,デフォルトでは実際に実行したテストの数を宣言しますが,必要に応じて自分で計算したテストの数を出力することもできるので,no_planでは対応できなかったforkがらみのテストなどでも正しく対応できるようになっています。

use strict;
use Test::More;

Test::More->builder->use_numbers(0); # テストが順不同でも許す
Test::More->builder->no_ending(1);   # child側の整合性チェックを省略する

if (my $pid = fork) {
    wait;
    pass "parent";
    done_testing(2);  # 明示的にテストの件数を指定する
}
else {
    pass "child";
}

ここではdone_testingを親のブロックのなかに収めていますが,子のブロックを抜けるときに明示的にexitすればdone_testingを最後に持っていくこともできます。

use strict;
use Test::More;

Test::More->builder->use_numbers(0); # テストが順不同でも許す
Test::More->builder->no_ending(1);   # child側の整合性チェックを省略する

if (my $pid = fork) {
    wait;
    pass "parent";
}
else {
    pass "child";
    exit;
}
done_testing(2);  # 明示的にテストの件数を指定する

もちろんno_planで対応できるようなテストであれば,done_testingの引数は省略できます。

use strict;
use Test::More;
if ($^O ne 'MSWin32') {
    pass;
}
pass;
done_testing;

また,done_testingはno_planと違ってテスト終了時に自動的に宣言部を追加する,という仕組みをとっていないため,done_testingにたどり着く前にテストが終わってしまった場合は「宣言部がない」というエラーを出すことも可能です。

たしかにdone_testingは便利ですが……

このように,done_testingは,正しく使えば従来のno_planが抱えていた問題をほとんどすべて解決できるようになったのですが,done_testingにも問題がないわけではありません。

たとえば,Test::NoWarningsというテストモジュールの例を見てみましょう。これはテストの実行中に警告が出なかったかどうかをENDブロックのなかで判定するのですが,この場合,単にdone_testingするだけでなく,テスト計画の数まで考慮してあげても,現時点では宣言部がテストのなかに埋め込まれてしまうためにテストに失敗します(done_testingの部分をENDブロックのなかに含めてもかわりません。なお,no_planはこのようなテストにも対応しています⁠⁠。

use strict;
use Test::More;
use Test::NoWarnings;

pass "without warning";

done_testing(2); # NoWarningsの分をひとつ追加

また,no_planと違って途中で(異常)終了した場合を検出できるようになったとはいえ,done_testingも,引数なしで使った場合は,期待したテストをすべて実行したかどうかの確認はできません。たとえば,このようにPODが埋め込まれたテストがあったとしましょう。

use strict;
use Test::More;

pass;

=pod

pass;

=pod

=cut

pass;

done_testing;

ご覧の通り,実はこのテストは=podディレクティブのくくり方が間違っていて,ふたつめの「pass;」がPODのなかに入り込んでしまっているのですが,ここではdone_testingを引数なしで使っているので,テストはもともとふたつしかなかったと「正しく」解釈して,正常終了します。もちろんそれは意図通りの結果ではありません。同様のことは,たとえば(意図とは違って)常に偽になってしまう条件式が含まれていたり,ブロックのくくり方が間違っていた場合などにも容易に起こることです。

だから,たしかにdone_testingにもよいところはあるのですが,どんな場合でもdone_testingで十分と主張するのは間違いですし,一般的にはdone_testingに頼るのではなく,明示的にplanを宣言するか,ほかの方法でテストの数を調べるほうがベターといえます。

次回は,そのような「実際に実行したテストの数」以外の方法でテストの数を調べようとするテストツールについてまとめてみましょう。

著者プロフィール

石垣憲一(いしがきけんいち)

あるときは翻訳家。あるときはPerlプログラマ。先日『カクテルホントのうんちく話』(柴田書店)を上梓。最新刊は『ガリア戦記』(平凡社ライブラリー)。

URLhttp://d.hatena.ne.jp/charsbar/