ちょっとしたトリックを思いついたので、備忘録。
Laravel(lumen)でプロジェクトを作成すると、PHPUnitの設定ファイル(phpunit.xml)が生成されます。
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="bootstrap/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Feature Tests">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
<testsuite name="Unit Tests">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>
</phpunit>
テスト用の環境変数設定は<php>
要素の<env>
要素に記述するわけですが、laravel(lumen)では環境変数の切り替えはDotEnv
で行っているわけですから、これも.env
ファイルに記述したいと思いませんか?
では、こんなファイルを作成しましょう。
<?php
require_once __DIR__.'/../vendor/autoload.php';
try {
(new Dotenv\Dotenv(__DIR__))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
echo ".env for test is missing.";
exit(1);
}
require_once 'bootstrap/app.php';
tests/.env
ファイルを読み込んで、本来のbootstrapファイルを呼び出すだけのラッパーです。
APP_ENV=testing
CACHE_DRIVER=array
SESSION_DRIVER=array
QUEUE_DRIVER=sync
最後にはphpunit.xml
を変更します。
bootstrap=
を先程のtests/bootstrap.php
に置き換えて、<php>
要素をバッサリ削除すればOKです。
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="tests/bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Feature Tests">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
<testsuite name="Unit Tests">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
</phpunit>
これでphpunitを実行すると、以下のようなシーケンスで処理が流れます。
phpunit(phpunit.xml)
→ tests/bootstrap.php
(ここでtests/.env
が読み込まれる) → bootstrap/app.php
こういう仕組みを導入しておくと、他のテストドライバからPHPUnitを実行する場合も同じ仕組みが使えます。
例えばPhingのPHPUnitタスクからテスト実行する場合は、bootstrap
にtests/bootstrap.php
を指定すればOKです。
<phpunit codecoverage="true" bootstrap="tests/bootstrap.php">
<batchtest>
<fileset dir=".">
<include name="tests/**/*Test.php" />
</fileset>
</batchtest>
</phpunit>