ユニットテストの際にインメモリの SQLite を使用することで、開発用のデータベースに影響を与えることなくテストを実行することができます。
前提
PHP | Laravel | PHPUnit |
---|---|---|
v7.2 | v5.5 | v6.5.5 |
セットアップ
まずはデータベースの接続設定を config/database.php
に追加します。
database
の項目に :memory:
を指定するのがポイントですね。
これによりデータの保存先がメモリ上になるようです。
config/database.php
return [
/* 中略 */
'connections' => [
'sqlite_testing' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
],
/* 中略 */
],
/* 中略 */
];
次にPHPUnitの設定を行います。<env>
にて環境変数が指定されるので、DB_CONNECTION
を追加し、値を上記で追加したキー sqlite_testing
としています。
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit>
<!-- 中略 -->
<php>
<env name="APP_ENV" value="testing"/>
<env name="DB_CONNECTION" value="sqlite_testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>
</phpunit>
プロジェクト作成直後のデフォルトコードで、すでに以下のように環境変数から接続先のデータベースを指定しています。
config/database.php
'default' => env('DB_CONNECTION', 'mysql'),
そのため、phpunit.xml
で DB_CONNECTION
を設定してやるとテスト実行時のみデータベースを切り替えられるわけです。
テストコード
tests/Unit/ExampleTest.php
<?php
namespace Tests\Unit;
use App\User;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 各テスト実行前に呼ばれる。
*
*/
protected function setUp()
{
parent::setUp();
// データベースマイグレーション
$this->artisan('migrate');
// 必要に応じてテストデータ挿入
$this->seed('ExampleTableSeeder');
}
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$user = User::create([
'name' => 'John Doe',
'email' => 'john@doe.com',
'password' => 'testing1234',
]);
$this->assertEquals(1, User::all()->count());
}
}
PHPUnitでは各テスト実行前に setUp
メソッドが呼び出されます。この setUp
メソッド内でマイグレーションおよび Seeder
を実行しています。
Seeder
の実行はお好みで、アプリの動作前提となるマスタデータなどを入れると良いでしょう。コマンドで言えば、以下を実行しているのと同じですね。
$ php artisan migrate
$ php artisan db:seed --class=ExampleTableSeeder
以上、LaravelのテストでインメモリSQLiteを使う方法でした。