LoginSignup
0
0

[Laravel] テスト実行時にテスト用データベースへ切り替わる仕組み

Posted at

要点

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です。

tests/Features/ExampleTest.php
<?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.ymldocker/mysql/create-testing-database.shというファイルが関係しています。

まず、docker-compose.ymlservices.mysql.volumesの箇所で、docker/mysql/create-testing-database.shを実行しています。

docker-compose.yml
#(略)

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を作成しています。

docker/mysql/create-testing-database.sh
#!/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では、テスト時に利用する環境変数の定義をすることができます。

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'へと切り替わり、
それによってtestingDBへ接続するようになるという仕組みです。

ちなみに、環境変数を定義している.envファイルのDB_DATABASEでは、開発時に使用するDBが定義されています。

.env
DB_DATABASE=developing  #(開発時に使用するDB名)

上の場合、開発時にはdevelopingというDBを使用するということになります。
そしてテスト時のみ、phpunit.xmlに定義されたtestingDBへ切り替えるということになりますね。


以上が、Laravelにおける「テスト実行時にテスト用データベースへ切り替わる仕組み」でした。

このあたりの知識は、ソフトウェアテストについて学びたての頃は学習するのに苦労するポイントかなと思います。
この記事がお役に立てたなら幸いです。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0