Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
12
Help us understand the problem. What are the problem?
@ucan-lab

Laravel × Docker でテスト用のデータベースコンテナを使う

新しい記事を書きました!
Docker × Laravel テスト用のデータベースコンテナを構築する


Laravel2 Advent Calendar 2019 - Qiita の 16日目 の記事です。

Laravel環境構築

ucan-lab/docker-laravel-alpine を元にLaravel環境を作ります。

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

データベースコンテナ構成

こちらの docker-compose.yml から抜粋です。

docker-coompose.yml
  db:
    image: mysql:8.0
    volumes:
      - db-store:/var/lib/mysql
      - ./logs:/var/log/mysql
      - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
    environment:
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASS}
      - MYSQL_ROOT_PASSWORD=${DB_PASS}
      - TZ=${TZ}
    ports:
      - ${DB_PORT}:3306

  db-testing:
    image: mysql:8.0
    volumes:
      - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
    tmpfs:
      - /var/lib/mysql
      - /var/log/mysql
    environment:
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASS}
      - MYSQL_ROOT_PASSWORD=${DB_PASS}
      - TZ=${TZ}
    ports:
      - ${DB_TESTING_PORT}:3306

db コンテナが通常の開発用DBコンテナ
db-testing コンテナがテスト用DBコンテナ

phpunit.xml

vendor/bin/phpunit を実行すると何も指定しない場合 phpunit.xml が読み込まれます。

phpunit.xml
    <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"/>
    </php>

<server> タグを <env> タグに書き換えます。

phpunit.xml
    <php>
        <env name="APP_ENV" value="testing" 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>

APP_ENVdocker-compose.yml にて環境変数として定義していますので、
phpunit.xml で既存の環境変数の上書きが必要です。

phpunit.xmlenvタグやserverタグを設定すると次のようなPHPコードになるイメージです。

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

Dockerを使ってるとココは結構ハマりどころかなと思います。

CreatesApplicationトレイトで一度だけマイグレーションを実行する

テストを書く際は TestCase を継承してテストを作ります。

TestCase クラスは CreatesApplication トレイトをインポートしてます。

この createApplication() メソッドは各テスト実行の際に必ず呼ばれるのでこのタイミングで初回のみテスト用データベースのマイグレーションを実行します。

tests/CreatesApplication.php
<?php declare(strict_types=1);

namespace Tests;

use Illuminate\Contracts\Console\Kernel;
use Illuminate\Support\Facades\Artisan;

trait CreatesApplication
{
    /**
     * @var bool
     */
    protected $isSetUpDatabase = false;

    /**
     * Creates the application.
     *
     * @return \Illuminate\Foundation\Application
     */
    public function createApplication()
    {
        $app = require __DIR__.'/../bootstrap/app.php';

        $app->make(Kernel::class)->bootstrap();

        $this->setUpDatabase();

        return $app;
    }

    /**
     * Run migration once
     */
    protected function setUpDatabase(): void
    {
        if ($this->isSetUpDatabase) {
            return;
        }

        Artisan::call('migrate:fresh');

        $this->isSetUpDatabase = true;
    }
}

テスト実行

$ make app
$ ./vendor/bin/phpunit

参考

関連記事

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
12
Help us understand the problem. What are the problem?