Laravel Sailで一番簡単にテスト用DBを用意する
こんにちは。
いつもテスト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