カラクリスタ

HTTP::Request::AsCGIを使ってCGI scriptをテストする方法

概要: HTTP::Request::AsCGI を使って CGI Application をテストする


最近 blosxom と menta とかの軽量 WAF を足して二で割ったような CGI Application を書いてるんだけど、 CGI Application のテスト方法について最近ノウハウがちょっと溜まってきたので、 Blog の記事にまとめてみる。

CGI Application のテストというと、簡易サーバを起動して実行するとか方法はいろいろあるわけだけど、 要するに CGI Application をテストするには CGI の実行環境と同じ環境変数を用意して CGI script を実行すればいいわけで、 そういうごにょごにょとした処理をしてくれるのがHTTP::Request::AsCGIというワケ。

で、HTTP::Request::AsCGI使ってテストを書くとこんな感じ。

#!perl

use strict;
use warnings;

use HTTP::Request;
use HTTP::Request::AsCGI;
use CGIApp;
use Test::More tests => 1;

{
my $req = HTTP::Request->new( GET => 'http://localhost/foo/bar.html' );
my $ctx = HTTP::Request::AsCGI->new($req)->setup;
my $app = CGIApp->new;

$app->run_application;

my $stdout = join q{\n}, $ctx->stdout->getlines;
is( $stdout, 'Hello world' );
}

HTTP::Request::AsCGI自体はそんなにややこしいことをしてないので、 HTTP::Request::AsCGIの処理自体は実際のコード見てもらったほうが早いと思う。 で、実際に最近書いてるテストコードではHTTP::Request::AsCGIがインストールされてなかったら、 テストをスキップするみたいなコードが追加してあったりする。

あと環境変数を指定したい場合はこんな感じで指定できる。

{
my $req = HTTP::Request->new( POST => 'http://localhost/foo/bar/baz' );
my $ctx = HTTP::Request::AsCGI->new( $req, $ENV_NAME => $ENV_VALUE )->setup;
}

ちなみにHTTP::Request::AsCGIのインスタンスをブロックで囲んでるのは、 HTTP::Request::AsCGIにデストラクタが指定されているため。

といってもまあ、

引用元: HTTP::Request::AsCGI 0.5

code:_ sub DESTROY my $self = shift; $self->restore if $self->{setuped && !$self->restored; }

これだけのコードなので手動で実行しても問題はないけど。

まあHTTP::Request::AsCGIを使えば、CGI Application のテストはだいぶスマートに書けると思う。 最近書いてるテストでもそんなややこしいことはしてないし。

というわけで今日はHTTP::Request::AsCGIの紹介でした。まあ POD みたら使い方なんて一発なんだけど。

ちなみに久しぶりのプログラミング関係のエントリ。最近プログラミングが復活してきましたよ。

#FIXME