こんにちは、ナイトレイ採用担当の牧野です。
Wantedlyをご覧の方に、ナイトレイのエンジニアがどのようなことをしているか知っていただきたく、Qiitaに公開している記事をストーリーに載せています。
少しでも私たちに興味を持ってくれた方は下に表示される募集記事もご覧ください↓↓
はじめに
株式会社ナイトレイの和田です。
普段、自社サービスの開発に取り組んでいます。
現在私が関わっているLaravelのプロダクトにPHPUnitテストを導入しました(そのプロダクトではユニットテストが省略されていました)。
その際に上記のタイトルに関する問題で少し悩んだので記事にして共有したいと思います。
前提として、この問題はテストDBを用いるテストに限ったものになります。
環境
Laravel 8.83.14
PHP 7.3.33
PHPUnit 9.5.20
テスト時にDB内のデータが吹き飛んでしまうケース
以下の条件が揃った時に発生する。
- (
config: cache
)コマンドを打つなどして、設定ファイルがキャッシュされた状態でテストを実行 - 実行されるテストファイル内で(RefreshDatabase)などのテーブル、もしくはテーブル内のデータを一回削除するような処理が施されている場合
理由としては、Laravelにおいて設定ファイルがキャッシュされた状態でテストを実行すると、phpunit.xml よりそのキャッシュが優先的に参照されるため。
これだけだと分かりにくいので、もう少し具体的に説明してみる。
テスト実行時に接続するデータベースをテスト用のものに自動で切り替えるためにはざっくり以下の手順を踏む。
・テスト用.envファイルの作成
-テストDBの接続情報などを環境変数で管理
・database.phpの編集
-テスト用DBの接続設定を記述する
・phpunit.xmlの編集
-テスト時に参照させたい.envやDBを設定
-上記で設定したものをテスト実行時に利用する
こうすることで、テスト実行時はテスト専用DBが使用されるようになる。
しかし、ここでもしキャッシュしていた場合、前述の通りphpunit.xml よりそのキャッシュが優先的に参照されてしまう。
そうなると、どうなるだろう?
テスト実行時にテスト用以外のDBに接続されてしまう。
テストではよく実行前にRefreshDatabaseなどでテーブルやテーブル内データを削除するので、 意図せず接続されてしまったテスト用以外のDB内のデータを誤って吹き飛ばしてしまう事態が発生しうる。
対応策
①開発環境ではconfig:cacheコマンドを使用しない
(config:cache)でキャッシュを作成できるが、ドキュメントにもあるように開発環境では非推奨である。
通常、本番デプロイメントプロセスの一部としてphp artisan config:cacheコマンドを実行する必要があります。アプリケーションの開発中は設定オプションを頻繁に変更する必要があるため、ローカル開発中はコマンドを実行しないでください。
②テスト実行前に「手動」でキャッシュをクリアする
(php artisan config:clear
)コマンドを叩くことで、キャッシュを消去することができる。
ドキュメントにも以下のような記述がある。
テストを実行する前は必ずconfig:clear Artisanコマンドを使用して設定のキャッシュをクリアしてください
③テスト実行時に「自動」でキャッシュをクリアする
phpunitが実行されると、phpunit.xmlのbootstrap属性に設定されているphpファイルが読み込まれることになっている(デフォルトではvendor/autoload.phpが設定されている)。
これを利用し、config:clearを含んだファイルを自作しそれに差し替えてあげれば、必ず全てのテストに先立ってキャッシュがクリアされる。
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
- bootstrap="vendor/autoload.php"
+ bootstrap="bootstrap/testing.php"
colors="true"
自作ファイル
+ <?php
+ system('php artisan config:clear');
+ require_once __DIR__ . '/../vendor/autoload.php';
キャッシュがクリアされたか確かめる方法
簡単な方法としては、キャッシュファイルの有無を確認すればよい。
前述の通り、(php artisan config:cache)で設定ファイルがキャッシュされる。
キャッシュはbootstrap/cache配下にconfig.phpとして作成される。
したがって、上記の設定後にテストを実行してみて、このconfig.phpが削除されたかどうか確かめればよい。
参考文献
Laravel8.x 設定
Laravel8.x テストの準備
Laravelにおけるキャッシュ問題について
いかがでしたか?ナイトレイでは、フロントエンド・バックエンド・アプリ開発など様々なメンバーが活躍しています。私たちは一緒に事業を盛り上げてくれるエンジニアメンバーを募集していますので、是非募集記事もご覧ください。
このような方におすすめ
✔︎ 自社Webサービスの開発で事業の発展に携わってみたい
✔︎ 自分が開発したものが顧客にどのように使われているのか知りたい(顧客の声を聞いてみたい)
✔︎ セールスチームなど、他部署のメンバーとコミュニケーションが取れる環境に興味がある
✔︎ 地理や地図が好きで仕事中も眺めていたい