Laravelでテスト用DBを作成するときにちょっとてこずったので、記録しておこうと思います。
##環境
Mac OS Catalina 10.15.5
Docker 19.03.8
docker-compose 1.25.5
Laravel 5.5.48
DockerImageは
PHP7.3.18
nginx1.19.0
MySQL5.7.30
を利用しました。
##したいこと
既に作成しているLaravelのプロジェクトにテスト用DBを追加したい。
新しくプロジェクトを開始する時に最初からDBを複数作っておきたい。
##MySQLで直接作成
一番先に思いつくのはこれですよね。
Laravelの.envファイルで指定してるユーザーでは新しくDBを作成できなかったので、
DockerでMySQLの環境に入り込み、とりあえず作成する。
$ docker exec -it [container name] bash
とりあえずrootで新しくDBを作成。
:/# mysql -u root -p
mysql> CREATE DATABASE testing_db; [testing_db はテスト用のDB名]
テスト用DBをLaravel環境で使用するので、そのユーザーに権限を渡します。
GRANT ALL ON `testing_db`.* TO 'forge'@'%' ; [forge のところはLaravelの環境に合わせる]
権限を先に渡してからLaravelのユーザーでDB作成しても良かったかも。
##UnitTest時にテスト用DBを使うよう指定する
LaravelにはPHPのUnitTestがいい感じに調整されて入ってるそうです。
それを利用してテストするのですが、その際に既にあるDBを操作しちゃうと大変なので、
先ほど作成したDBを使用するようにします。
...
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<!-- テスト環境用DBを追加 -->
<env name="DB_DATABASE" value="testing_db"/>
</php>
...
Laravelのバージョンによって少し表記が違うようですが、名前やDBの指定方法は同じはず。
###テスト用環境も用意
次にテスト用環境も用意します。.env
ファイルをコピーして.env.testing
ファイルを作成。
DB_DATABASE=testing_db さっき作ったDB名に変更する
テスト用envファイルを作ったので、これを利用してマイグレーションします。
Seederがあるのならそれも利用すると、本番とほぼ同じ環境をさっき作ったDBに作成できました。
プロジェクトが動いてるdockerコンテナの中に入り込んでから、
# php artisan migrate --seed --env=testing
これで環境は整ったはず。migrate:refresh
でも動いてくれました。
あとはテストを記述して実行すると、作成したDBに対してデータ入れたりしてくれるはずです。
##プロジェクト初回起動時にDB作っちゃう
Laradockとかを利用してると、割と簡単にできるそうです。
私はLaradockを使ってなかったのですが、全然難しくありませんでした。
初心者なので「難しくない」という結論に至るまでが長いんですよね。。。
利用するdocker-compose.yml
ファイルで、DBがマウントするところの記述を少し変えます。
docker-compose.ymlファイルが置いてある場所と同じ階層に、sql
フォルダを作成して、
...
volumes:
# これを追加
- ./sql:/docker-entrypoint-initdb.d
...
とマウントするように記述。フォルダ名はsql
としてますが、なんでもいいです。
というか、docker-entrypoint-initdb.d
にマウントさせれば階層もどこでもいいです。
上記のdocker-entrypoint-initdb.d
に、拡張子が.sql
とかのファイルを置いておくと、初回起動時に自動で内容を読み込んで実行してくれるらしいです。
docker-composeでmysql使うとき初回起動時に複数のDBを作る方法
で、その場所にマウントしてるsql
フォルダに次のファイルを置いておきます。
CREATE DATABASE IF NOT EXISTS `testing_db` COLLATE 'utf8_general_ci' ;
GRANT ALL ON `testing_db`.* TO 'forge'@'%' ;
Laradockにはこれのテンプレートが既に作成されてるので、別のプロジェクトからコピーしてきました。
コピーしなくても直接記述すればいい話ですが。
これで初回起動時に作成してくれるはずです。
あとは前述の方法で環境整えたりしたらOK。
##参考
docker-composeでmysql使うとき初回起動時に複数のDBを作る方法
Laradockのmysqlで初期起動時に複数DBを作成する(ハマった)
laravelでDBテストコードを書く前の設定すべきこと
LaravelとPHPUnitでDB操作クラスのユニットテストを行う
めっちゃ勉強になりました。ありがとうございました。
初心者なので間違ってる所とかありましたらぜひご指摘ください。