メメメモモ

プログラミング、筋トレ、ゲーム、etc

.cgiで書かれたアプリをPlack::Testでテストする

各処理が.cgiファイルで分かれているアプリをPlack::Testでテストする方法です。

Plack::App::CGIBinでPSGIアプリに変換する

.cgiファイルが置かれているディレクトリで以下のようなapp.psgiを置きます。

#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;

use Plack::Builder;
use Plack::App::CGIBin;

my $basedir = dirname(__FILE__);

builder {
    mount '/' =>
          Plack::App::CGIBin->new( root => $basedir, exec_cb => sub { 1 } )->to_app;
};

これで、PSGIアプリになります。

$ plackup app.psgi

といったコマンドで起動すれば、以下のようなURLでアクセスできるようになります。

http://localhost:5000/index.cgi

Plack::Testでテストする

後は普通のPSGIアプリのようにテストができます。
Plack::Testでテストする場合は以下のようになります。

use strict;
use warnings;
use Test::More;
use Plack::Test;
use HTTP::Request::Common;

use Plack::Loader;
use Plack::Util ();

my $app = Plack::Util::load_psgi('app.psgi');
test_psgi $app, sub {
    my $cb = shift;

    my $res;

    $res = $cb->(GET "/index.cgi");
    is $res->code, '200';

    $res = $cb->(GET "/hello.cgi?name=memememomo");
    is $res->content, "Hello, memememomo";

    $res = $cb->(POST '/post.cgi', { name => 'memememomo' });
    is $res->content, "Hello, memememomo";

    $res = $cb->(GET '/redirect.cgi');
    is $res->code, '301';
};                                                                                                           

done_testing();


Test::WWW::Mechanize::PSGIを使った場合は、以下のようになります。

use strict;
use warnings;
use Plack::Test;
use Plack::Util;
use Test::More;
use Test::Requires 'Test::WWW::Mechanize::PSGI';

my $app = Plack::Util::load_psgi 'app.psgi';

my $mech = Test::WWW::Mechanize::PSGI->new(app => $app);
$mech->get_ok('/index.cgi');

$mech->get_ok('/hello.cgi?name=memememomo');
$mech->content_like(qr/Hello, memememomo/);

$mech->post_ok('/post.cgi', { name => 'memememomo' });
$mech->content_like(qr/Hello, memememomo/);
                                                                                                             
$mech->get_ok('/redirect.cgi');

done_testing;


サンプルで作ったプログラム
https://gist.github.com/1142366