Mojoを使って自作ウェブアプリをよりポータブルに!

第2回 Mojoを使えばテストも簡単!

この記事を読むのに必要な時間:およそ 4 分

リクエストオブジェクトの中身

このリクエストオブジェクトの正体は,Mojo::Message::Requestのインスタンスです。ここにはさまざまなメソッド,オブジェクトが格納されていますが,ふだんよく使うのはこのくらいでしょうか。

$tx->req->param(パラメータ名)

クエリストリングやフォームデータのパラメータを返します。

$tx->req->method

リクエストのメソッド(GET,POSTなど)を返します。

$tx->req->is_multipart

リクエストがマルチパートのフォームデータかどうかを返します。

$tx->req->cookie(クッキー名)->value

クッキーの値を返します。

$tx->req->headers->content_length

Content-Lengthヘッダの値を返します。

$tx->req->headers->content_type

Content-Typeヘッダの値を返します。

$tx->req->headers->header(ヘッダ名)

任意のヘッダの値を返します。

$tx->req->url->path

PATH_INFOの値を返します。

$tx->req->upload(パラメータ名)->file->move_to(移動先)

アップロードされたファイルを移動します。

そのほかのメソッドや,各メソッドの詳細については該当するクラスのPODやソースコードをご覧ください。

CGIとして動かしてみる

さて,このSimpleBBS,連載第1回のように開発用のスタンドアロンサーバで動かしてもよいのですが,お手元にApacheなどのサーバがあるならCGIとして動作させてみましょう。

本当はシェル(コマンドライン)から「perl script/simple_bbs cgi」を実行するとCGI向けの出力が得られるのですが,この形ではブラウザから実行しづらいので,別に起動スクリプト(index.cgi)を用意します(use libの中身はお手元の環境にあわせて適宜修正してください⁠⁠。

#!/usr/bin/perl
use strict;
use warnings;
use lib qw(
  /home/ishigaki/mojo/lib
  /home/ishigaki/mojo/simple_bbs/lib
);
use Mojo::Server::CGI;

$ENV{MOJO_APP} = 'SimpleBBS';

Mojo::Server::CGI->new->run;

サーバの設定ファイルにCGIの実行権限を追加して再起動したら,ブラウザからいまのCGIを実行してみてください。送信したテキストがテキストボックスの下に表示されていけばひとまず成功です。

テストを書こう

ところで,最初にお断りしたように,このCGIにはいくつもバグがあります。たとえば,テキストボックスから半角の0を送信してみてください。本当は0というテキストが追加されるべきなのに,なにも起こらなかったはずです。

このような場合,みなさんならどうするでしょうか?

この程度の分量であれば,いきなりソースコードを見ても問題なく直せるでしょう。でも,コードがもっと複雑になってきた場合,そして同じようなフォームがたくさんある場合,いきなりコードに手を入れるのは下策です。ここでやってしまったケアレスミスをほかのところで繰り返さない保証はないのですから,せめてテスト項目に加えておくべきですし,できれば自動的にテストできるようテストコードを書きたいところです。

ウェブアプリケーションをテストする場合,一般的にはWWW::Mechanizeのようなモジュールを使って本番環境と同じ動作をする検証用アプリケーションにアクセスし,フォームに値を入れたりリンクをたどったりしていくのが常道ですが,Mojoの場合,テストにあたってわざわざ検証用の環境を構築する必要はありません。たとえば,0に対するテストであれば,このように書けます。

use strict;
use warnings;
use Test::More tests => 1;
use SimpleBBS;
use Mojo::Transaction::Single;

my $app = SimpleBBS->new;
{
    my $tx = Mojo::Transaction::Single->new;
    $tx->req->param('text' => 0);
    $app->handler($tx);
    like $tx->res->body => qr{<p>0</p>};
}

テストを実行してみる

このテストをt/false_value.tという名前で保存したら,実際にテストを走らせてみましょう。シェル(コマンドライン)からこのようにタイプしてください。

> perl script/simple_bbs test

いまの段階では当然テストは失敗します。問題の箇所を修正しましょう。差分はこうなります。

@@ -13,7 +13,7 @@
         open my $fh, '>', $file or die $!;
         close $fh;
     }
-    if ($tx->req->param('text')) {
+    if (defined $tx->req->param('text')) {
         open my $fh, '>>', $file or die $!;
         print $fh $tx->req->param('text'), "\n";
         close $fh;

著者プロフィール

石垣憲一(いしがきけんいち)

あるときは翻訳家。あるときはPerlプログラマ。先日『カクテルホントのうんちく話』(柴田書店)を上梓。最新刊は『ガリア戦記』(平凡社ライブラリー)。

URLhttp://d.hatena.ne.jp/charsbar/