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