Laravel3、単体テストの準備
この記事は、Laravel3でのテストについてのシリーズです。
- その1:単体テストの準備
- その2:例外のテスト
- その3:Eloquentモデルのテスト
- その4:バリデータークラスのテスト
- その5:リポジトリークラスのテスト
- その6:コントローラークラスのテスト
- その7:結合テスト
テストの対象は、以下のシリーズで作成した、りんごテーブルに対する簡単なCRUD操作プログラムに対するものです。
- 参照:Laravel3で活かす例外
- 参照:クラスのディレクトリー構造をひと工夫
- 参照:例外と小さなクラス達
- 参照:小さなクラスで読み込み削除
- 参照:小さなクラスで更新
phpunit.xml
今まで作成した各クラスに対してphpunitを使用したテストの環境を整えましょう。
Laravel3ではコマンドラインツールのArtisanを利用し、phpunitを実行できます。しかし、これはphpunitの機能を制限してしまうだけで、利便性が上がるものではありません。ですから直接phpunitを実行する方法をこのサイトで紹介してきましたし、フォーラムにも投稿しました。
Laravel4では、コマンドラインツールから外れ、直接phpunitを実行する形式になります。
phpunitはコマンドのオプションとして多くのことが指定できますが、それでは使い勝手が悪いため、オプションを定義したphpunit.xmlファイルを作成し、コマンドとしてはphpunit
のみを入力、実行するのが通常の使用方法でしょう。
では、phpunit.xmlの紹介です。インストールしたトップのディレクトリー、つまりartisanのある場所と同じディレクトリー内に設置してください。
<?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="laravel/cli/tasks/test/phpunit.php" verbose="true" > <!-- Laravelの実行環境をテスト用にセット --> <php> <env name="LARAVEL_ENV" value="test" /> </php> <testsuites> <testsuite name="Unit Test"> <directory suffix="Test.php">application/tests</directory> </testsuite> </testsuites> </phpunit>
今回はテストに必要な最小限度の設定を行なっています。
bootstrapでLaravelのテスト用のbootstrapコードを指定しています。このbootstrapコードによりLaravelの動作環境が設定されます。
最後のtestsuitesがテストの対象を指定しています。applicationディレクトリー下のtestsディレクトリー内のファイルで、サフィックスがTest.phpのものをphpunitはテスト対象として扱います。Laravelのartisanでは".test.php"です。phpunitのデフォルトに合わせて設定しています。サフィックスですのでお好みで変更してください。
さて、真ん中で定義しているのが環境変数です。Laravelは動作環境により設定ファイルを切替える仕組みになっています。実行時の環境変数にLARAVEL_ENVがあれば、その値が環境変数として使用されます。テスト実行時のみ"test"に変更しています。
環境の設定
テスト時は本番や開発環境とは異なったデータベースなどを使用したいでしょう。そのため、前述の方法で実行環境を"test"に変更します。
つまりテスト時に優先的に使用されるのはapplication/config/testディレクトリーの中の設定という事になります。
今回はデータベースなどのデータ保管場所をメモリ上に置くことで、テストのスピードアップを行います。多くのクラスでは、設定ファイルで指定するドライバーにより、ストレージの切り替えが行えます。テスト目的のため、メモリを使用するドライバーが用意されており、テストをスピードアップできるようになっています。
cache.phpです。今回は未使用です。
<?php return array( 'driver' => 'memory', );
session.phpです。
<?php return array( 'driver' => 'memory', );
database.phpです。データベースには直接メモリーに保存するドライバーは用意されていません。しかし、SQLiteでメモリにデータベースを設定できますので、それを使用します。
<?php return array ( 'profile' => false, 'fetch' => PDO::FETCH_CLASS, 'default' => 'sqlite', 'connections' => array ( 'sqlite' => array ( 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', ), ), );
application/testsの構成
testsのディレクトリー構成です。application下の構成をコピーし、テスト対象ファイルと同じ相対パスにテストクラスを設置しています。テストスタブはTestStubsディレクトリー下にテスト対象を表すディレクトリーを作成し、その対象で使用するスタブなどをディレクトリー内に設置します。
+application +tests +TestStubs +AppleController +AppleRepo +application +ProjectH +Execeptions +ExecutionErrorExceptions +Repositories +Services +Validators +controllers +models
テストスタブはIoCコンテナにより置き換えます。IoCコンテナはLaravelのクラスです。つまり、Laravelのオートローダーで指定できるようにしなくてはなりません。
既に、プロジェクトの本体であるProjectHフォルダーをPSR-0規約でのオートロード先として指定しています。その配列に、テストスタブのディクトリーを付け加えましょう。start.phpでしたね。
Autoloader::namespaces(array( 'ProjectH' => path('app').'ProjectH', 'TestStubs' => path('app').'tests/TestStubs', ));
テストスタブのディレクトリーを付け加えた所で、アプリケーションの実行結果は変わりません。PSR-0規約の場合、ベンダー名が一致するかどうかを最初に確認します。本体のProjectHはTestStubsより前に定義されているため、先にチェックされます。ですから、本体の実行結果には影響ありません。(もし、逆だとしても、配列一回の参照の違いでしかありません。ファイルの存在をチェックするためのファイルアクセスが余計に発生することもありません。)
さて、これでテストケースを書く準備ができました。次の記事から、単体テストを書いていきましょう。