Happy Testing Perl

第3回 Test::Declareの紹介

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

第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のコードです。

著者プロフィール

小林篤(こばやしあつし)

株式会社モバイルファクトリー システム開発部所属。

携帯公式サイト構築をはじめ,公式サイトで利用する楽曲を管理するプロジェクト開発を担当。インフラ関係ではメールサーバを構築運用したりもしている。

ネコが大好きだが,ネコアレルギーなこまったぷろぐらま。

ブログはhttp://d.hatena.ne.jp/nekokak/など。

コメント

コメントの記入