« Releasing Starlet 0.10, now runs faster than ever | Main | (Twitter の XSS 脆弱性に関連して) 構造化テキストの正しいエスケープ手法について »

August 27, 2010

テストケースの実行にあわせて Apache を起動・終了する方法

ウェブアプリケーションやライブラリの結合テストを行う段階になると、実際に Apache を起動してテストを実行したくなります。しかし、そのためにいちいち Apache の設定ファイルを修正して httpd を再起動して、とやっていては面倒です。特に複数のプログラムを同時に開発していると、あっちをテストしたらこっちが動かなくなって… なんてなったりして嫌気がさしてきます。

そこで、テストを実行する際に、環境毎に異なる以下のような問題を吸収しつつ、テスト専用に設定された Apache を自動的に起動終了してくれる Perl モジュール:Test::Httpd::Apache2 を書きました。

  • 環境によって、インストールパスが違う (/usr/local/apache/bin だったり /usr/sbin だったり)
  • 環境によって LoadModule の要不要や、ロードするパスが違う
  • 環境によってプログラム名が違う (Debian 系では httpd ではなく apache2)
  • Apache/2.0 と 2.2 でモジュール名が変わっているケースがある (mod_access と mod_authz_host)

使い方は簡単。テストコードの先頭で、Test::Httpd::Apache2 のインスタンスを生成すると、自動的に TCP の空きポートを探して Apache が起動するので、そのアドレスに HTTP クライアントからアクセスするだけです。起動された Apache は、Test::Httpd::Apache2 のインスタンスが解放されるタイミングで終了され、一時ファイルも自動的に消去されます。

use Test::Httpd::Apache2;

my $httpd = Test::Httpd::Apache2->new(
    required_modules => [ qw(perl) ],  # mod_perl をロード
    custom_conf => << 'EOT',
<Location />
  SetHandler perl-script
  ...
</Location>
EOT
);

my $root_url = "http://" . $httpd->listen . "/"; # 起動した host:port から URL 生成

# あとはテスト
...

そして、テスト本体が Perl のコードである必要はないので、PHP や他の言語のテストを実行するためのラッパーとして使うこともできます。

use Test::Httpd::Apache2;

my $httpd = Test::Httpd::Apache2->new(
    required_modules => [ qw(php5) ],  # mod_php をロード
    custom_conf => << 'EOT',
DocumentRoot "docroot"
SetHandler php5-script
EOT
);

# 起動した host:port から URL を生成して、環境変数に登録
$ENV{ROOT_URL} = "http://" . $httpd->listen . "/";

# my_test.php を実行
system('php', 'my_test.php') == 0
    or die "my_test.php failed: $?";

Test::mysqldTest::postgresql と組み合わせると、データベースを使うウェブアプリの結合テストが気軽に書けそうで夢が広がりまくりんぐ。

まだ荒削りなモジュールなので、改善提案やパッチ等お待ちしております。インストールは cpan -i Test::Httpd::Apache2、リポジトリは github.com/kazuho/p5-test-httpd-apache2 にあります。

それでは、have fun!

TrackBack

TrackBack URL for this entry:
http://bb.lekumo.jp/t/trackback/404050/24945827

Listed below are links to weblogs that reference テストケースの実行にあわせて Apache を起動・終了する方法:

Comments

Post a comment