要点
Laravelでは、テスト用DBの作成と切り替えを全て自動で行ってくれます。
一連の仕組みに関わっているファイルは以下の通り。
- テスト用DBの作成 →
docker-compose.yml
およびdocker/mysql/create-testing-database.sh
- テスト用DBヘの切り替え →
phpunit.xml
および.env
前提
Laravel Sailを使ったDocker環境で開発をしているという前提で話を進めます。
- macOS 13.5.2
- PHP 8.2.11
- Laravel Framework 10.28.0
- laravel/sail v1.25.0
- Docker 23.0.5
- laravel/breeze v1.25.0
本題
はじめに
アプリケーション開発において、テストを実行するとDBに保存されているデータが全て消去されます。
そのため、テストを行う際は必ずテスト用DBに切り替える必要があります。
Q. そもそも、なぜテスト実行時にDBの全データが消去されるの?
A. 1つ1つのテストの独立性を保つため。
解説:
テスト(機能テスト)では、DBへのデータ登録・取得・更新等のDB接続も含めた検証を行うため、各テストの実行後にDBの全データを消去し初期化を行います。もし仮に初期化を行わなかった場合、後続の別のテストに影響を与えてしまい、正しいテスト結果が得られなくなってしまう可能性があります。
ちなみに、DBの初期化を行うためには、テストクラス内でIlluminate\Foundation\Testing\RefreshDatabase
トレイトを使用すればOKです。
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
// RefreshDatabaseトレイトを使用し、テスト実行後にDBを初期化
use RefreshDatabase;
/**
* 基本的な機能テスト例
*/
public function test_basic_example(): void
{
$response = $this->get('/');
// ...
}
}
詳細はLaravelドキュメントをご確認下さい。
→ https://readouble.com/laravel/10.x/ja/database-testing.html
「テスト用DBに切り替える」ためには、
切り替えのための設定が必要なのはもちろんですが、まずその前にテスト用DB自体を作成する必要があるいうことになります。
「手順が多くて大変じゃん...」と思いきや、
Laravelではテスト用DBの作成と切り替えを全て自動で行ってくれるため、自分で何も設定する必要はありません。
それでは、テスト用DBの作成と切り替えが実際にどのような仕組みによって実現されているのか見ていきましょう。
テスト用DBの作成
テスト用DBの作成には、docker-compose.yml
とdocker/mysql/create-testing-database.sh
というファイルが関係しています。
まず、docker-compose.yml
のservices.mysql.volumes
の箇所で、docker/mysql/create-testing-database.sh
を実行しています。
#(略)
volumes:
- 'sail-mysql:/var/lib/mysql'
- './docker/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
そして、docker/mysql/create-testing-database.sh
では、testing
という名前のDBを作成しています。
#!/usr/bin/env bash
mysql --user=root --password="$MYSQL_ROOT_PASSWORD" <<-EOSQL
CREATE DATABASE IF NOT EXISTS testing;
GRANT ALL PRIVILEGES ON \`testing%\`.* TO '$MYSQL_USER'@'%';
EOSQL
これによって、私たちが自分でtesting
DBを作らなくて済んでいるわけですね。
テスト用DBへの切り替え
では、テスト用DBへの切り替えはどのように行っているのでしょうか。
これには、phpunit.xml
と.env
というファイルが関係しています。
phpunit.xml
では、テスト時に利用する環境変数の定義をすることができます。
<!-- 略 -->
<php>
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<!-- ↓ テスト用DB 'testing'を使用する設定 -->
<env name="DB_DATABASE" value="testing"/>
<!-- 略 -->
</php>
<env name="DB_DATABASE" value="testing"/>
という記述により、テスト時のみDB_DATABASE
環境変数の値が'testing'へと切り替わり、
それによってtesting
DBへ接続するようになるという仕組みです。
ちなみに、環境変数を定義している.env
ファイルのDB_DATABASE
では、開発時に使用するDBが定義されています。
DB_DATABASE=developing #(開発時に使用するDB名)
上の場合、開発時にはdeveloping
というDBを使用するということになります。
そしてテスト時のみ、phpunit.xml
に定義されたtesting
DBへ切り替えるということになりますね。
以上が、Laravelにおける「テスト実行時にテスト用データベースへ切り替わる仕組み」でした。
このあたりの知識は、ソフトウェアテストについて学びたての頃は学習するのに苦労するポイントかなと思います。
この記事がお役に立てたなら幸いです。