Catalystでテストする testデビュー
Testなんて今までろくに使ったことがなかったのですが、YAPCの牧さんのみて、これはやらんといかんよねー。 手間排除できそうだし、ミスも減りそうだしーいいことずくめっぽいZO!って事でCatalystでテストデビュー
いきなりエラーの巻
巻さんお資料の通りとりあえず既存のCatalystアプリでテストしてみた
Perl Makefile.PL make make test
が、いきなりエラー
[info] myapp powered by Catalyst 5.7012
t/controller_logic.......ok 1/3[info] *** Request 1 (1.000/s) [22955] [Fri May 23 21:21:39 2008] ***
[debug] "GET" request for "logic" from "127.0.0.1"
[debug] Arguments are "/logic"
[error] Unknown resource "logic"
[error] Unknown resource "logic"
コントローラーlogicにlogicでアクセスできんよって事で、そうですそれが何か?って事だけど、これはテストを修正すべきなのか、Catalystを修正すべきか?
そのほかにもsettingコントローラにsettingリソースが見つからないよと怒られた。
[debug] Arguments are "/setting" [error] Unknown resource "setting" [error] Unknown resource "setting"
sub index: Private {}をおいた。 indexなくてもいいじゃない!人間だもの
ようやくまっさらな状態でテストが通る。
t/02pod..................skipped all skipped: set TEST_POD to enable this test t/03podcoverage..........skipped all skipped: set TEST_POD to enable this test
PODはskipでおっけー
ではテストファイルをみてみる
MyApp/t/controller_setting.tファイルをみてみた。
ok( request('/setting')->is_success, 'Request should succeed' );
!! /settingにアクセスしようとしていたのはこいつだった!というか俺あほすぎ
でもようやくわかってきた
ok( request('パス')->is_success, 'Request should succeed' );
ってやってちゃんとレスポンスが返ってくれば正しく動作するかどうかをテストできることがわかった。
ここまできてようやくCatalyst::Manual::Tutorial::Testingを読んだ
http://search.cpan.org/~zarquon/Catalyst-Manual-5.7011/lib/Catalyst/Manual/Tutorial/Testing.pod
There are a variety of ways to run Catalyst and Perl tests (for example, perl Makefile.PL and make test), but one of the easiest is with the prove command. For example, to run all of the tests in the t directory, enter: $ prove --lib lib t
perl Makefile.PL; make; make testはやる必要なくて
prove --lib lib t で ./t/ディレクトリの中のテストファイルをすべて実行してくれるようだ。
CATALYST_DEBUG=0 prove --lib lib t
これでテストサーバのデバッグ機能をOFFにして余計なメッセージを表示させないようにできる
CATALYST_DEBUG=0 TEST_POD=1 prove --lib lib -v t
さらに-vをつけることでテストケース毎に表示するようになった。
おれおれテストを書く
CatalystHelperが書き出してくれるデフォルトテストの中はこの通り
use strict; use warnings; use Test::More tests => 3; BEGIN { use_ok 'Catalyst::Test', 'myapp' } BEGIN { use_ok 'myapp::Controller::setting' } ok( request('/setting')->is_success, 'Request should succeed' );
Catalyst::Test
- get
ok( gett('/setting')->is_success, 'Request GET should succeed' );
GETでテスト ゲッツ!
- request
ok( request('/setting')->is_success, 'Request should succeed' );
テストに書いてあったまんま、パスにリクエストする
- local_request
不明?
- remote_request
リモートからのリクエスト? LWP使用
結局Catalyst::Testはウェブレイヤーのテスト(コントローラのテスト)が目的なので、ロジックのテストは無理。
Catalyst::Manual::Tutorial::Testing これをみるとTest::WWW::Mechanize::Catalystでいろいろできるようだけど、結局これもウェブレイヤーでのテストという事で、実際の環境に近いところでのテスト用だと考えればいいいっぽい。
純粋なロジック部分をテストするにはどうするんだ?って事で、牧さんのスライド、ぐぐって調べてみる限り、Catalystとは分離して書くのが良さそうだ。Catalyst::Model::Adaptorつかえって事のようで。
それとついつい$c->stashをグローバル変数のように使ってしまう。 こうなるとものすごくテスト、デバッグがしにくい。 これは駄目。
http://blog.hide-k.net/archives/2007/10/catalystmodelad.php
MyApp/HogeMoge.pm .... ロジック
MyApp/Model/HogeMoge.pm .... HogeMogeクラス Model Adapterのヘルパーが作ってくれる
などとするとすっきりしそうです。
とここまできて思ったことは、Catalystでテストを行おうとすると、ロジック部分がCatalystに依存していると、テストしにくい。 Model::Adaptor使えばいいんだろうが、弊害もありそうな気がする。 一番いいのはテストサーバ経由(ウェブ経由)しないテストがかければいいんじゃね?って事で、次はそれに挑戦してみようと思う。
思ったこと。
アプリよりテストを先に書くといいのかもしれない。
いまさらだけど、テストは書くべし。
テストを軽くやろうと思ったら、設計やらなにやらいろいろと勉強になりました。
今までのやり方ではあかんなと思いました。是非テスト書いた方がいいよと書いてみるテスト
参考サイト
http://conferences.yapcasia.org/ya2008/talk/971
http://d.hatena.ne.jp/nitsuji/20070526/1180157242
http://www.sixapart.jp/techtalk/2006/10/dev-vox-test.html
http://search.cpan.org/~zarquon/Catalyst-Manual-5.7011/lib/Catalyst/Manual/Tutorial/Testing.pod
http://search.cpan.org/~mramberg/Catalyst-Runtime-5.7013/lib/Catalyst/Test.pm