Test::Stream──新しいテストフレームワーク
Test::Builder
はほぼすべてのテストモジュールのベースとなっているフレームワークですが、Test::Builder
自体の機能を拡張したい場合はそれぞれのテストモジュールがTest::Builder
のメソッドにパッチを当てていくしかありませんでした。
Test::Builder2の開発スタート、そして中止
このような状況を受けて、Test::More
のメンテナーだったMichael G SchwernによってTest::Builder
を根本的に作りなおすTest::Builder2の開発がスタートしました。これはモノシリックな構造だったTest::Builderを全面的に書き換え、
Test::Streamの開発スタート
Test::Builder2
の開発中止が決まったタイミングでTest::More
のメンテナーを引き継いだChad Granumが開発を進めている新しいテストフレームワークがTest::Stream
です。
Test::Stream
の特徴は次のとおりです。
is
やlike
がリファレンスもテスト可能に- TAP出力のUTF-8サポート
- プラグイン機構の導入
- テスト結果のオブジェクト化
is
がリファレンスもテストできるようになったので、is
とis_
を使い分ける必要がなくなりました。比較したいデータを渡せばTest::Stream
側でよしなに対象のデータ型を判断してくれます。また、
use Test::Stream -V1;
is( +{ lang => 'perl5' }, +{ lang => 'perl6' }, '違う言語?';
done_testing;
テストが失敗したときのメッセージもとてもわかりやすくなりました。先ほどのテストを実行すると次のように表示されます。
not ok 1 - 違う言語?
# Failed test '違う言語?'
# at stream.t line 2.
# +--------+-------+----+-------+
# | PATH | GOT | OP | CHECK |
# +--------+-------+----+-------+
# | {lang} | perl5 | eq | perl6 |
# +--------+-------+----+-------+
1..1
プラグイン機構の導入とともに、Test::More
相当の機能はもちろんのこと、Test::Exception
、Test::Output
といったメジャーなテストモジュール相当の機能がプラグインとして提供されていますし、
テストモジュールを作るうえでは、
use Test::Stream -V1, -Tester;
my $results = intercept {
is(1, 1, 'success test');
is(1, 2, 'failure test');
};
is($results->[0]->name, "success test");
like(
$results->[1]->diag,
[qr/Failed test 'failure test'/],
);
done_testing;
Test::Stream
はCPANにアップされているのでcpanm Test::Stream
でインストールできます。執筆時点
Perl 6のテスト
最後にPerl 6のテストについて少し紹介します。
2015年のPerl界隈の最大のニュースと言えば、
Testモジュール
Perl 6にはそのものずばりTest
というテストモジュールが用意されていて、Test::More
とTest::Exception
相当のテスト関数が用意されています。テストのスタイルも従来のPerl
use v6;
use Test;
is("Perl6".chars, 5, "文字列の長さのテスト"); ―(1)
my $str = "Perl 6 will be available this Christmas";
like($str, rx:i/christmas/, "正規表現のテスト"); ―(2)
subtest { ―(3)
# Perl 6のオブジェクト機構を使ってクラスを定義
class Person {
has Str $.name is rw;
has Int $.age is rw;
}
# オブジェクトの作成と、プロパティの設定
my $person = Person.new;
$person.name = "Larry";
$person.age = 61;
# プロパティのテスト
is( $person.name, 'Larry', 'name属性のテスト');
cmp-ok($person.age, &infix:«>=», 60, 'age属性のテスト'); ―(4)
}, 'オブジェクトのテスト';
throws-like( ―(5)
sub { die "throw exception" },
X::AdHoc, # dieの送出する例外の型は、X::AdHoc
message => "throw exception",
"例外のテスト"
);
done-testing; ―(6)
Perl 5のテストに慣れている人ならば、
(1) (2) のis
、like
は、Test::More
の同名のテスト関数と同じ(3) のsubtest
は、引数の順番が変わった以外は Test::More
のsubtest
と同じ(4) のcmp-ok
は、関数名が (Perl 6の命名付与規約に合わせて) 変わったのと、 比較演算子によって多少指定のしかたが変わった以外は Test::More
のcmp_
と同じok (5) のthrows-like
は、Perl 6で導入された例外クラスをテストするテスト関数 (6) のdone-testing
は、Test::More
のdone_
と同じtesting
また、
テストの実行と結果の確認
テストを実行すると結果がTAP形式で出力される点は、
$ perl6 perl6-test.t
ok 1 - 文字列の長さのテスト
ok 2 - 正規表現のテスト
ok 1 - name属性のテスト
ok 2 - age属性のテスト
1..2
ok 3 - オブジェクトのテスト
1..3
ok 1 - code dies
ok 2 - right exception type (X::AdHoc)
ok 3 - .message matches throw exception
ok 4 - 例外のテスト
1..4
prove
コマンドはprove
コマンドをそのまま利用します。Perl 6のテストも拡張子は.t
を使用するので、--exec perl6
オプションを付けて実行します。
$ prove --exec perl6 perl6-test.t
perl6-test.t .. ok
All tests successful.
...
Result: PASS
Perl 6の仕様をテストするroast
Perl 5では
さらに、Test
モジュールが使われています。Perl 6を学習するためには、
まとめ
Perlのテストモジュールの使い方と作り方を一通り解説し、
Perlのテストは、
さて、