第3回目を担当する小林です。 今回は私が開発したPerlモジュールのTest::Declareについて紹介します。
Test::Declareの特徴
Test::Declareには,以下の特徴があります。
- テストコードをDSL風に(宣言的に)書く事を重点に置いている
- それによりテストコード自体の見やすさを向上させることができる
- 宣言的にテストを書く事により,一体なにを目的としたテストなのかがわかりやすくなる
Test::Declareでは,Test::More,Test::Deep,Test::Exception,Test::Warn,Test::Outputのfunctionをexportしているので,Test::Declareを1つuseするだけで,これらのモジュールのfunctionが利用可能となります。 これらのテストモジュールが提供するfunctionは通常よく使うものですので,毎回すべてをuseしなくても利用できるようにしてあります。
Test::Declareの使用例
Test::Declareを利用すれば,テストコードの見やすさが向上すると言いましたが,たとえばTest::Moreのfunctionを使ったテストの例として,Data::ObjectDriverで書かれているテストを取り上げてみたいと思います。
Data::ObjectDriverは,Six Apartで開発されているORマッパーで,CPANにもアップされているモジュールです。そのモジュールのsvn HEADの11-sql.tというテストコードでは以下のような記述となっております。
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のコードと比べて,変わった書き方をしていると思いますが,もちろんPerlのコードです。

