36
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Docker × Laravel テスト用のデータベースコンテナを構築する

Last updated at Posted at 2020-08-11

Laravelでデータベースのテストを行う時、RefreshDatabasefactoryなど便利なメソッドやトレイトが用意されています。
これらを使ってテストを行いますが、Dockerでデータベースコンテナ一つでやると開発で使ってるデータがクリアされてしまってあまりよろしくないです。

今回はテストする時はテスト用のデータベースを使うように設定します。

前提

当記事は上記の記事の補足になる記事です。

Laravel環境構築

$ git clone git@github.com:ucan-lab/docker-laravel.git
$ cd docker-laravel
$ make create-project

環境

  • PHP 7.4.4
  • Laravel 7.27.0

手順

docker-compose.yml を編集する

$ docker-compose down

docker-compose.ymlDockerfile を変更する場合は予めコンテナを破棄しておくと良いです。

docker-compose.yml
  db-testing:
    build: ./infra/docker/mysql

db-testing サービスの設定を services 配下に追記します。

$ docker-compose up -d

コンテナを作成して起動します。

$ docker-compose ps
           Name                          Command              State                 Ports              
-------------------------------------------------------------------------------------------------------
docker-laravel_app_1          docker-php-entrypoint php-fpm   Up      9000/tcp                         
docker-laravel_db-testing_1   docker-entrypoint.sh mysqld     Up      3306/tcp, 33060/tcp              
docker-laravel_db_1           docker-entrypoint.sh mysqld     Up      0.0.0.0:3306->3306/tcp, 33060/tcp
docker-laravel_web_1          nginx -g daemon off;            Up      0.0.0.0:80->80/tcp

db-testing のコンテナが起動していればokです。

.env.testing

$ cp .env.example .env.testing
$ php artisan key:generate --env=testing
.env.testing
DB_CONNECTION=mysql
DB_HOST=db-testing
DB_PORT=3306
DB_DATABASE=laravel_local
DB_USERNAME=phper
DB_PASSWORD=secret

サンプルのテストを作成

$ php artisan make:test SampleTest

tests/Feature/SampleTest.php ファイルが生成されるので、下記のように書き換えます。

backend/tests/Feature/SampleTest.php
<?php declare(strict_types=1);

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\User;

class SampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testExample()
    {
        factory(User::class)->create(['name' => 'sample']);
        $this->assertEquals(1, User::where('name', 'sample')->count());
    }
}

テスト実行

$ php artisan test
   PASS  Tests\Unit\ExampleTest
  ✓ basic test

   PASS  Tests\Feature\ExampleTest
  ✓ basic test

   PASS  Tests\Feature\SampleTest
  ✓ example

  Tests:  3 passed
  Time:   3.74s

テストが通ったことを確認できればokです。
db データベースのデータも消えていないことを確認してください。

補足: 開発用データベースが消える場合1

テスト用のデータベースコンテナを参照してくれない場合は、設定ファイルがキャッシュされている可能性があります。

$ php artisan config:clear

忘れ防止のため、composerスクリプトに入れるのもいいかもしれません。

composer.json
{
    "scripts": {
        "test": [
            "@php artisan config:clear",
            "@php artisan test"
        ]
    }
}
$ composer test

補足: 開発用データベースが消える場合2

docker-compose.ymlenvironment でサーバー環境変数にデータベースの接続情報等を設定している場合です。
.env.testing よりもサーバー環境変数が優先されてしまいます。

対策としては、 phpunit.xml で環境変数を上書きできます。

phpunit.xml
    <php>
        <env name="APP_ENV" value="testing" force="true"/>
        <env name="DB_CONNECTION" value="mysql" force="true"/>
        <env name="DB_HOST" value="db-testing" force="true"/>
        <env name="DB_PORT" value="3306" force="true"/>
        <env name="DB_DATABASE" value="laravel" force="true"/>
        <env name="DB_USERNAME" value="phper" force="true"/>
        <env name="DB_PASSWORD" value="secret" force="true"/>
        <env name="BCRYPT_ROUNDS" value="4"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="MAIL_DRIVER" value="array"/>
        <env name="QUEUE_CONNECTION" value="sync"/>
        <env name="SESSION_DRIVER" value="array"/>
    </php>

注意としては、 server タグではなく、 env タグで指定します。

$_ENV['APP_ENV'] = 'testing'; // env タグ
$_SERVER['APP_ENV'] = 'testing'; // server タグ

参考

過去記事

以前に似た記事を書いてました...

36
24
1

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
36
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?