Laravel3、単体テストの準備

タグ: Laravel3   テスト志向  

この記事は、Laravel3でのテストについてのシリーズです。

テストの対象は、以下のシリーズで作成した、りんごテーブルに対する簡単なCRUD操作プログラムに対するものです。

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より前に定義されているため、先にチェックされます。ですから、本体の実行結果には影響ありません。(もし、逆だとしても、配列一回の参照の違いでしかありません。ファイルの存在をチェックするためのファイルアクセスが余計に発生することもありません。)

さて、これでテストケースを書く準備ができました。次の記事から、単体テストを書いていきましょう。