第3回目を担当する小林です。 今回は私が開発したPerlモジュールのTest::Declareについて紹介します。
Test::Declareの特徴
Test::Declareには、
- テストコードをDSL風に
(宣言的に) 書く事を重点に置いている - それによりテストコード自体の見やすさを向上させることができる
- 宣言的にテストを書く事により、
一体なにを目的としたテストなのかがわかりやすくなる
Test::Declareでは、
Test::Declareの使用例
Test::Declareを利用すれば、
Data::ObjectDriverは、
use Data::ObjectDriver::SQL; use Test::More tests => 64; my $stmt = ns(); ok($stmt, 'Created SQL object'); ## Testing FROM $stmt->from([ 'foo' ]); is($stmt->as_sql, "FROM foo\n"); $stmt->from([ 'foo', 'bar' ]); is($stmt->as_sql, "FROM foo, bar\n"); ## Testing JOINs $stmt->from([]); $stmt->joins([]); $stmt->add_join(foo => { type => 'inner', table => 'baz', condition => 'foo.baz_id = baz.baz_id' }); is($stmt->as_sql, "FROM foo INNER JOIN baz ON foo.baz_id = baz.baz_id\n"); $stmt->from([ 'bar' ]); is($stmt->as_sql, "FROM foo INNER JOIN baz ON foo.baz_id = baz.baz_id, bar\n"); #nop... sub ns { Data::ObjectDriver::SQL->new }
ぱっとみで一体なにをテストしているのかわかりにくくないでしょうか?
そこでTest::Declareの出番です。Test::Declareを使うと、
use Data::ObjectDriver::SQL; use Test::Declare; plan tests => blocks; my $stmt; sub ns { Data::ObjectDriver::SQL->new } sub reset_sql { $stmt->from([]); $stmt->joins([]); } describe 'Create SQL object' => run { test 'DOD::SQLのオブジェクトが作れる事' => run { ok ns; }; }; describe 'Testing FROM' => run { init { $stmt = ns; }; test 'fooをfrom句に設定できること' => run { $stmt->from([ 'foo' ]); is $stmt->as_sql, "FROM foo\n"; }; test 'foo barをfrom句に設定できること' => run { $stmt->from([ 'foo', 'bar' ]); is $stmt->as_sql, "FROM foo, bar\n"; }; cleanup { reset_sql; }; }; describe 'Testing JOINs' => run { init { $stmt = ns; }; test 'fooとbazをJOINできること' => run { $stmt->add_join(foo => { type => 'inner', table => 'baz', condition => 'foo.baz_id = baz.baz_id' }); is $stmt->as_sql, "FROM foo INNER JOIN baz ON foo.baz_id = baz.baz_id\n"; }; test 'barをfrom句に追加できること' => run { $stmt->from([ 'bar' ]); is $stmt->as_sql, "FROM foo INNER JOIN baz ON foo.baz_id = baz.baz_id, bar\n"; }; cleanup { reset_sql; }; };
元の例よりもいくらか何をやっているテストなのかわかりやすくなったのではないでしょうか? 通常のPerlのコードと比べて、
Test::Declareにおけるテスト件数
Test::Declareを利用すると、
Test::DeclareはTest::Moreをベースにより使いやすいようにラッピングしているモジュールですので、
plan tests => 1;
といった、
これが意外に面倒で、
use Test::More tests => 64;
これでは、
plan tests => blocks;
と一度設定すれば、
まとめ
Test::Declareを使うにあたっての構成としてはこのようになりますので参考にしてください。
plan tests => blocks; describe 'テストする範囲など記述' => run { init { # DBのsetupなど、テストに必要な前処理を記述 }; test '実際にテストを記述 テストがこけた場合ここのメッセージが表示されます' => run { is foo, 'foo'; is bar, 'bar', '個別にメッセージを設定する事も可能'; }; cleanup { # テスト時に発生したキャッシュや、データの変更などを # 元に戻す }; }
Test::DeclareではこのようにTestのためのフレームワークを提供します。 実際の使用例としては
を参考にしてみてください。
Test::Declareは弊社のテストスクリプトで多く利用しているモジュールですが開発自体はcodereposで行っています。
現時点ではTest::WWW::Declareほどdeclarativeではありませんが今後改良を加える予定です。もし興味のある方がいらっしゃったらcodereposで一緒に開発しましょう!