🙌

Laravel Sailで一番簡単にテスト用DBを用意する

2022/07/16に公開

こんにちは。
いつもテストDBを用意しているのに、なぜかテストにローカルDBを使われてしまい、毎回データがリセットされてしまっていました。
かなり辛い。。

最近はDockerを再び使い始めたので、Laravel Sailでテスト用DBを用意して、テストするところまで、めちゃめちゃ時間がかかったので、ログとして残しておきます。

Laravel Sailは自動でテスト用DBを作ってくれる

Laravel Sailのdocker-compose.ymlのmysqlの部分を見ると、こうなっています。

    mysql:
        image: 'mysql/mysql-server:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ROOT_HOST: "%"
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
        volumes:
            - 'sail-mysql:/var/lib/mysql'
            - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
        networks:
            - sail
        healthcheck:
            test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"]
            retries: 3
            timeout: 5s

このうちの ./vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh という部分に注目します。

これは、mysqlを構築した一番最初に実行されるシェルを指定しています。

じゃあ、 ./vendor/laravel/sail/database/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というデータベースがなかったら作る」っていう動作をしています。
つまりtestingというテスト用のデータベースが最初に自動で作られる仕組みになっているのです。

注意点

僕はこれにかなりハマりました。

唯一の注意点は、 .envに記載するmysqlのユーザー名を「root」にしないことです。

rootにすると、既に存在するrootユーザーに加えて、もう一つのrootユーザーができてしまって、
testingデータベースを作る際に、「ユーザー名がrootというのが2つあるけどどちらで作れば良いのじゃ??」と混乱して、元々存在していた方のrootで作ってしまうことになります。

簡単にいうと、 mysqlのユーザー名を「root」にしてしまうと、 testingデータベースがいつまで経っても作成されません。
(作成されているけど、接続する権限がありません)

3時間くらい格闘したので、皆さんはご注意ください。。。

以上で、Laravel Sailでテスト用DBを用意しようでした!!

Discussion