Apache::Testを使用したテストの定義
デフォルトの01app.tに記述されたテストでは、Catalystを直接実行しているため、Apacheと連携したCatalystを呼び出すことはできません。ここでは、Apache::Testを使用したテストコードを紹介します。
use strict; use warnings; # (1)関連するモジュールを指定 use Apache::Test; use Apache::TestUtil; use Apache::TestRequest; # (2)planでテストの数を指定 plan tests=> 1; # (3)Apache::TestRequestのGETメソッド my $res = GET '/'; # (4)Apache::TestUtilのt_cmpで比較 ok t_cmp($res->code, 200, "check request '/'");
(1)関連するモジュールを指定
最初にApache::Test関連のモジュールを指定します。Apache::TestUtilはテストに関係するさまざまなユーティリティメソッドを提供しているモジュールです。
Apache::TestRequestはHTTPリクエストを発行する機能をもったモジュールで、LWP::UserAgentのサブクラスとして、GET以外にもPOSTなどのHTTPメソッドに対応したさまざまなメソッドが用意されています。Apache::TestRequestを使用することで、ポート番号などのテスト用の設定パラメータを読み込んで、自動的にこれらの値を使用してテストできるようになります。
Apache::TestRequestは、HTTPのGetやPostなどに対応するメソッドの他に、ファイルのアップロードを行うメソッドなどが提供されています。例えばGET()メソッドは、URLを受け取って、そのURLへリクエストした結果のレスポンスとしてHTTP::Responseを返します。
GET関連のメソッドには次のようなものがあります。
| メソッド名 | 説明 |
| GET | 指定されたURLに対するリクエストを発行し、結果としてHTTP::Responseを返す |
| GET_STR | 指定されたURLに対するリクエスト結果を文字列として返す。GET($url)->as_stringのショートカット |
| GET_BODY | GET($url)->contentのショートカット |
| GET_BODY_ASSERT | レスポンスのBodyの内容についてチェックする必要がある場合に使用 |
| GET_OK | GET($uri)->is_successのショートカット |
| GET_RC | GET($uri)->codeのショートカット |
| GET_HEAD | 指定されたURLに対して受け取ったレスポンスのヘッダを返す |
このGETと同様のメソッドがHEAD/POST/PUTについても用意されています。
(2)planでテストの数を指定
前回に出てきたTest::Moreと同様のplanメソッドで実行するテストの数を指定します。Apache::TestにはTest::Moreと同名のメソッドをいくつか持つため、これらを同時に使おうとすると問題が発生します。この問題を回避するための方法については後述します。
また、Apache::Testには、needで始まるメソッドがいくつか定義されており、これをplanメソッドの最後の引数に指定することで、前提条件を指定できます。例えばSSLを必要とする場合には、「plan tests => 5, need_ssl;」のように指定します。need*メソッドには、次のようなものが用意されています。
| メソッド名 | 説明 |
| need_http11 | HTTP/1.1サポートを必要とする |
| need_ssl | SSLを必要とする。デフォルトではエクスポートされない |
| need_cgi | mod_cgi/mod_cgidがインストールされていることを必要とする |
| need_min_apache_version | 要求するApacheの最小バージョンを指定する |
| need_module | 必要とするApacheのCモジュール、またはPerlのモジュールを指定する |
その他のneed*メソッドについては、Apache::Testをご参照ください。
(3)Apache::TestRequestのGETメソッド
Apache::TestRequestモジュールのGETメソッドを使用して「/」に対するアクセスを行います。GETでは引数として、HTTP::Responseオブジェクトを返すため、codeやcontentなどのメソッドを使用することで、リターンコードやコンテンツ文字列などを取得できます。
(4)Apache::TestUtilのt_cmpで比較
Apache::TestUtilモジュールからはt_cmpメソッドを使用しています。このメソッドは次のような引数を取ります。
t_cmp($received, $expected, $comment);
$receivedは受け取った値、$expectedは比較する値、そして$commentにはコメントを指定します。Apache::TestUtilで定義されている主要なメソッドには、このほかにファイルやディレクトリを操作するものや、ファイルを監視するものなどがあります。
# t_cmp 値の比較。通常のt_cmpの戻り値はok()メソッドに渡す
ok t_cmp(1, 1, "1 == 1?");
# 配列やハッシュなども比較出来る
t_cmp({1 => [2..3,{5..8}], 4 => [5..6]},
{1 => [2..3,{5..8}], 4 => [5..6]},
"hash of array of hashes");
# t_is_equal 等しい場合には1を、それ以外の場合には0を返す
t_is_equal($a, $b);
# 書き込みモードでファイルを開き、ファイルハンドルを返す
# $filenameで指定されたファイルが存在しない場合にはディレクトリも含めて作成される
# このとき作成されたファイルはプログラム終了時に自動的に削除される
my $fh = t_open_file($filename);
# /foo/barディレクトリを作成
t_mkdir("/foo/bar");
# /foo/barディレクトリを削除
t_rmtree("/foo/bar");
okメソッドは、これもApache::Testモジュールに定義されているメソッドでTest::Moreのokと同様の動きをします。
ここで紹介した以外のユーティリティメソッドについては、Apache::TestUtilを参照ください。
Test::Moreと同居させる
Apache::TestとTest::Moreでは、ok、plan、skipなど同名のメソッドをエクスポートしており、同時に使おうとするとメソッド名が衝突して問題が発生します。
この問題を回避するためには、use行に「-withtestmore」または「:withtestmore」オプションを指定する必要があります。
これらの違いについてですが、「:withtestmore」を指定した場合にはTest::Moreのplanを使用するようになります。この場合には、use行にApache::TestとTest::Moreの両方を指定する必要があります。
use Apache::Test qw(:withtestmore);
use Test::More;
# Test::More::plan()
plan tests => 1;
# Test::More::ok()
ok ('yes', 'testing ok');
Apache::Testでは、mod_perlハンドラ側のテストを記述することもできます。この場合にはApacheのリクエストレコード情報にアクセスするためのクラスである、Apache2::RequestRec - Perl API for Apache request record accessorsを使用することにより、必要な情報を得ることができるようになります。
「-withtestmore」を指定した場合にも内部ではTest::Moreが呼び出されるのですが、planについてはApache::Testの機能を持ったplanとして動作するようになります。このplanを指定する際にApache2::RequestRecオブジェクトを渡す必要があります。こちらを設定するには、use行にはApache::Testだけを指定します(Test::Moreの設定は不要です)。
use Apache::Test qw(-withtestmore);
sub handler {
my $r = shift;
# Apache::Testのplan同様にApache2::RequestRecを
# 受け取ることの出来るTest::More::plan()
plan $r, tests => 1;
# Test::More::ok()
ok ('yes', 'testing ok');
}
2010年4月12日にPerl-5.12.0がリリースされました。このリリースでは、連載1回目の記事で紹介した、Perl-5.10.0で発生するCatalyst::Develインストールの問題も解決されています。
筆者もまだそれほどさわってはいないのですが、おおむね問題なく動作しています。Catalystを最新版のPerlで動かしたい場合には、5.12.0を検討してみてはいかがでしょうか。
まとめ
本記事では、Catalystを使用して実装したWebアプリケーションを、mod_perlを使用してApacheと連携させる環境を構築する方法について説明しました。またApache::Testを使用してmod_perl経由でのCatalystアプリケーションをテストする方法について簡単にではありますが説明しました。
さて、次回は、これまで紹介できなかったプラグインやモジュールについて、いくつか紹介していく予定です。
参考資料
- モダンPerl入門(牧 大輔、翔泳社、2009年)
- Catalyst-Manual-5.8004
- mod_perl
- Running and Developing Tests with the Apache::Test Framework
