Laravel テスト周りの設定


Laravelを使った開発時のテスト周りの設定の覚え書きです。

# 環境
・Laravel 5.8.35
・PHP 7.1.3
・PHPUnit 7.5.16

# 1. テスト用DBの作成
DBのデータを取り扱う処理をテストすることがあると思われますので、テスト用のDBを作成します。
普段の開発で使用しているDBをそのまま使用することもできますが、デメリットが多いのでテストで使用するDBは別に作成するのが無難でしょう。
DBの名前はphpunit.xml(後述)の記述との整合性がとれていればなんでも大丈夫です。

DBを作成したら、必要に応じてmigrationやseedingなどを行います。
このときartisanコマンドを使用すると思いますが、**データベースを指定するオプションを忘れないよう注意してください。**config/database.phpの'connections'内に追記した項目名(後述)を指定してください。

```
php artisan migrate --database=[config/database.phpの'connections'内に追記した項目名]
php artisan db:seed --database=[config/database.phpの'connections'内に追記した項目名]
```

# 2. config/database.phpにテスト用DBの設定を追加
テスト用DBを作成したら、config/database.phpに設定を追加します。記述場所は、'connections'の配列の中です。今回は開発環境でMySQLを使用していますので、同じくMySQLの設定を追記します。

```php

    'connections' => [

        'sqlite' => [
            'driver' => 'sqlite',
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
        ],
        //開発用DB
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

        'pgsql' => [
            'driver' => 'pgsql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '5432'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'schema' => 'public',
            'sslmode' => 'prefer',
        ],

        'sqlsrv' => [
            'driver' => 'sqlsrv',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '1433'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
        ],

        //テスト用DB
        'mysql_test' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => 'test_db',
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

    ],

```
上記の'mysql_test'の項目がテスト用DBの設定です。'database'の項目だけテスト用DBの名前に変更して、あとは開発用DBの設定をそのままコピペで基本的には大丈夫みたいです。
今回は設定の項目名を'mysql_test'としましたが、phpunit.xml(後述)の記述との整合性がとれていれば、なんでも大丈夫です。

# 3. phpunit.xmlの編集
PHPUnitの設定ファイルであるphpunit.xmlを編集します。
<php>タグ内でテスト用のenvやDBなどの設定を記述します。今回は以下のように編集しました。

```php
    <php>
        <server name="APP_ENV" value="testing"/>
        <server name="BCRYPT_ROUNDS" value="4"/>
        <server name="CACHE_DRIVER" value="array"/>
        <server name="MAIL_DRIVER" value="array"/>
        <server name="QUEUE_CONNECTION" value="sync"/>
        <server name="SESSION_DRIVER" value="array"/>
        <server name="DB_DATABASE" value="test_db"/>
        <server name="DB_CONNECTION" value="mysql_test"/>
    </php>

```
"DB_DATABASE"を"test_db"(テスト用に作成したDBの名前)
"DB_CONNECTION"を"mysql_test"(config/database.phpで追記した項目名)
にしました。

テスト用にenvファイルを作成している場合もここで設定できます。
.env.testing などという名前でenvを作成しておき、

```php
<server name="APP_ENV" value="testing"/>
```
とすると適用されます。テスト用のenvがない場合はデフォルトのenvファイルが適用されます。

これでテストを実行する準備が整いました。🎉

# トラブルシューティング
#### phpunit.xmlの設定が反映されない🤢
・テスト用のDBを作成してphpunit.xmlに記述しているのに、テストを実行するとなぜか開発用のDBが使用されている
・テスト用にenvファイルを作成してphpunit.xmlに記述しているのに適用されていない
などの場合

```php
<server name="DB_DATABASE" value="test_db" force="true"/>
<server name="DB_CONNECTION" value="mysql_test" force="true"/>
```
force="true"のオプションを試してみてください。

#### force="true"を書いてもphpunit.xmlの設定が反映されない🤮
キャッシュクリアのコマンドを実行して再度試してみてください

```
php artisan config:clear
```

#### 何をやってもテスト用の設定が反映されない🤯
ググって原因をひとつずつ潰していくしかないです。
この状態に陥ったことがありますが、テスト用DBを作成し直してイチから設定しなおしました。