計画的に実行するのはよいことですが
前回も紹介したように、
use strict;
print "1..10\n"; # 宣言部
for (1..10) {
print "ok $_\n";
}
このような宣言部の存在は、
単純そうに見えるTest Anything Protocolも、
skip_all
Perl 1.
use strict;
print "1..0\n";
exit;
これはいまでも特定の機能、
use strict;
use Test;
if ($^O eq 'MSWin32') {
plan tests => 0;
exit;
}
plan tests => 1;
ok 'tests for unix';
いまどきのTest::Moreでは意図しないところでテストがスキップされてしまうのを防ぐためtestsに0を指定することはできなくなっているので、
use strict;
use warnings;
use Test::More;
eval 'require Some::Module';
plan skip_all => 'this test requires Some::Module' if $@;
unless ($ENV{RELEASE_TESTING}) {
plan skip_all => 'set RELEASE_TESTING to test';
}
skip
ただし、
use strict;
use Test;
plan tests => 2;
skip('this test fails', 1 == 0);
ok 'portable test';
いまどきの書き方ならこうなりますね。
use strict;
use warnings;
use Test::More tests => 2;
SKIP: {
skip 'this test fails', 1;
ok 1 == 0;
}
pass 'portable test';
スキップするといっても、
> perl skip.t 1..2 ok 1 # skip this test fails ok 2 - portable test
todo
skipは上手に使えば便利な仕組みですが、
当初のtodoは、
use strict;
use Test;
plan tests => 2, todo => [1];
ok 0;
ok 1;
このテストを実行すると、
> prove todo.t todo.t .. # Failed test 1 in todo.t at line 4 *TODO* # todo.t line 4 is: ok 0; todo.t .. ok All tests successful. Test Summary Report ------------------- todo.t (Wstat: 0 Tests: 2 Failed: 0) TODO passed: 2 Files=1, Tests=2, 0 wallclock secs ( 0.03 usr + 0.03 sys = 0.06 CPU) Result: PASS
ただし、
use strict;
use warnings;
use Test::More tests => 2;
TODO: {
local $TODO = 'not implemented';
fail 'todo';
}
pass 'ok';
こちらの書き方の場合、
no_plan
このTODOの例のように、
たとえば特定の環境ではスキップしたいテストがあったとしましょう。伝統的な書き方では最初にテストの件数を宣言しなければなりませんから、
use strict;
print "1..2\n"; # 宣言部
if ($^O ne 'MSWin32') {
print "ok 1\n";
}
else {
print "ok 1 # Skip\n";
}
print "ok 2\n";
このくらいであればスキップの機構を使わず、
use strict;
my $total = $^O ne 'MSWin32' ? 2 : 1;
print "1..$total\n"; # 宣言部
my $count = 0;
if ($^O ne 'MSWin32') {
printf "ok %d\n", ++$count;
}
printf "ok %d\n", ++$count;
これを21世紀風のTest Anything Protocolで書き直すと、
use strict;
my $count = 0;
if ($^O ne 'MSWin32') {
printf "ok %d\n", ++$count;
}
printf "ok %d\n", ++$count;
print "1..$count\n"; # 宣言部
ここではいちいち自分でカウンタの値を増やしていますが、
no_planの問題点
ところが、
use strict;
use Test::More 'no_plan'; # Test::Moreの宣言部はここ
if ($^O ne 'MSWin32') {
pass;
}
pass;
# Test Anything Protocolの宣言部はここに出力
このTest::Moreのテスト計画の宣言部と実際にTest Anything Protocolの宣言部が出力される場所のズレは、
たとえば、
あるいは、
use strict;
use Test::More 'no_plan';
if (my $pid = fork) {
wait;
pass "parent";
}
else {
pass "child";
}
これは、
use strict;
use Test::More tests => 2;
Test::More->builder->use_numbers(0); # テストが順不同でも許す
Test::More->builder->no_ending(1); # child側の整合性チェックを省略する
if (my $pid = fork) {
wait;
pass "parent";
}
else {
pass "child";
}
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";
done_testing(2); # 明示的にテストの件数を指定する
}
else {
pass "child";
}
ここではdone_
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_
use strict;
use Test::More;
if ($^O ne 'MSWin32') {
pass;
}
pass;
done_testing;
また、
たしかにdone_testingは便利ですが……
このように、
たとえば、
use strict;
use Test::More;
use Test::NoWarnings;
pass "without warning";
done_testing(2); # NoWarningsの分をひとつ追加
また、
use strict;
use Test::More;
pass;
=pod
pass;
=pod
=cut
pass;
done_testing;
ご覧の通り、
だから、
次回は、