カラクリサイクル

『輝かしい青春』なんて失かった人の雑記

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

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

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

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

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

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