概要
- テストコード実行時にだけ接続するテーブルを用意して設定する方法をまとめる
方法
-
テスト用DBの作成
-
今回は手動で実施するがDockerなどで環境構築している場合、docker-compose.ymlなどに記載してコマンド一つで構築できるようにしたほうがいいかもしれない。
-
MySQLにログインして下記SQL句を実行してテスト用DBを作成する。(筆者はlaravel_testingというDB名で作成した。)
create database laravel_testing;
-
show databases;
を実行して正常にDBが作成されたことを確認する。 -
下記SQL句を実行して只今作成したDBの権限を設定する。(laravelの.envに記載されているDBアクセスユーザーが書き込みをできるようにする。)
grant all on laravel_testing.* to MySQLユーザー名;
-
-
テスト用.envの作成
-
既に存在する.env.exampleをコピーして.env.testingを作成する。
cp .env.example .env.testing
-
下記コマンドを実行して.env.testing用のAPP_KEYを発行する。
php artisan key:generate --env=testing
-
DB_DATABASE
の値をlaravel_testing
に変更する。.env.testingAPP_ENV=testing DB_DATABASE=laravel_testing
-
-
テスト時に使うDBの設定
-
laravelのアプリケーションディレクトリ内にある
phpunit.xml
を開く。 -
コメントアウトされている
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
を修正して下記のように記載する。(こちらでテスト時に使用するDB名を設定している。)phpunit.xml<env name="DB_DATABASE" value="laravel_testing"/>
-
-
テストコードの記載
-
あとは任意のFeatureテストコードにsetUp()関数を定義して下記のように記載すればテスト毎にマイグレーションとシーダーを実行してくれる。(トレイトの呼び出しもお忘れなく。シーダーを実行する時はRefreshDatabaseトレイトではなくDatabaseMigrationsトレイトを呼び出さないとダメなので注意)
FooTest.phpuse DatabaseMigrations; public function setUp(): void { parent::setUp(); Artisan::call('migrate:fresh --seed'); }
-
筆者はFeatureテスト用のベースクラスを別途作成しそのクラスを各Featureクラスで継承するようにしている。
-
Featureテスト用のベースクラス
FeatureBaseTestCase.php<?php namespace App\Tests; use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Support\Facades\Artisan; use Tests\TestCase; class FeatureBaseTestCase extends TestCase { use DatabaseMigrations; public function setUp(): void { parent::setUp(); Artisan::call('migrate:fresh --seed'); } }
-
Featureテストクラス
PostContentControllerTest.php<?php namespace Tests\Feature\Content; use App\Tests\FeatureBaseTestCase; class PostContentControllerTest extends FeatureBaseTestCase { const URL = '/api/content'; public function test_投稿内容が登録できる(): void { $url = self::URL; $requestBody = [ 'content' => 'XXX', ]; $response = $this->post($url, $requestBody); $response->assertCreated(); } }
-
-
おまけ
-
単純にテスト時だけDBトランザクションを貼ってほしい場合、下記のようにDatabaseTransactionsクラスをuseしてあげればよいかも。
use Illuminate\Foundation\Testing\DatabaseTransactions; class FooTest extends TestCase { use DatabaseTransactions; }
参考文献