Laravelでテスト駆動開発をする際の環境構築として初期設定をまとめていきます。
テストの実行方法、記述方法、テスト用のデータベース設定までまとめていきます。
なお、Laravel 11系からはテストフレームワークの Pest に対応するようになってますが、Laravelを新しく立ち上げた時にデフォルトで設定されているのは PHPUnitなので、デフォルト設定で手軽に使える方法かなとPHPUnitの解説をしていきます。
目次
とりあえずテストを実行してみる
Laravelはプロジェクト作成時からすでにテストが作成されているため、簡単に実行する事ができます。
$ composer create-project laravel/laravel example-app
$ cd example-app
$ php artisan --version
Laravel Framework 11.8.0
$ php artisan test
PASS Tests\Unit\ExampleTest
✓ that true is true
PASS Tests\Feature\ExampleTest
✓ the application returns a successful response 0.07s
Tests: 2 passed (2 assertions)
Duration: 0.11s
# phpunitコマンドでテストの実行も可能
$ ./vendor/bin/phpunit
PHPUnit 11.1.3 by Sebastian Bergmann and contributors.
Runtime: PHP 8.2.19
Configuration: /path/to/example-app/phpunit.xml
.. 2 / 2 (100%)
Time: 00:00.058, Memory: 26.00 MB
OK (2 tests, 2 assertions)
簡単ですね。
用意されているのはクラスファイル等の挙動を確認する Unitテストと、HTTPレスポンスを模倣して実際のWebブラウザで表示される内容を確認する Featureテストが用意されています。
作成済みのファイルはこちら
ポイントとしては
- Unitテストは
use PHPUnit\Framework\TestCase;
を継承 - Featureテストは
use Tests\TestCase;
を継承
している点です。この違いで実行できる処理が変わります。
データベースの書き込みをテスト
前述の内容は公式ドキュメントにもありますが、データベースの書き込みをテストする際に問題が発生した経験があります。
(後述する Environment の項目にはありますが、これがデータベースに関係する事だったというのは初見では解りづらいかと感じます。)
機能的には準備されてはいるので、私なりに解釈した使い方をまとめていきます。プロジェクトによっては別の使い方をしているかもしれませんので、他の方法をご存知の方は使いやすい方を選択してください。
.env.testing の用意
まずは、テスト実行時のデータベース環境を用意します。
$ cp .env .env.testing
.env.testing
は phpunit.xml
ファイルに記述されている
<env name="APP_ENV" value="testing"/>
によって決定したファイル名です。環境変数 APP_ENV
の値によって .env.〇〇
が読み込むものが決定します。
ただし、.env
の設定値はキャッシングされる対象になっているため、場合によってはキャッシングの削除が必要です。
# .env をキャッシングするコマンド (通常は開発環境での実行は必要無い)
$ php artisan config:cache
or
$ php artisan optimize
# .env のキャッシングを削除するコマンド
$ php artisan config:clear
or
$ php artisan optimize:clear # 開発環境ではこれで全てのキャッシュを削除するのがオススメ
要するに phpunit.xml の設定で .env.testing
を読み込む設定になっていても、既存の .env でキャッシングされている内容の方が優先されるので config:clear を実行することが推奨されます。
( 自分の環境で発生していた問題の原因が公式で言及されていたこれだったと気づくのに結構時間がかかりました )
この場合に問題になるのは気軽に phpunit の実行をしてしまうと開発中の画面で表示されているテストデータが消えてしまう場合が考えられます。自分で操作するテストデータと、テストコードで確認するためのテストデータの保存先は分けておくのが無難です。
テスト環境のデータベースを準備
.env.testing
にテスト環境のデータベースを作成する設定を追加します。
~~~ 中略 ~~~
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
DB_DATABASE=/path/to/example-app/database/database.testing.sqlite
# DB_USERNAME=root
# DB_PASSWORD=
~~~ 中略 ~~~
今回はsqliteでテスト用のデータベースを設定しましたが、公開環境と同じデータベース環境を用意しましょう。mysqlで公開しているのであれば テスト用のデータベースも mysqlにします。
データベースについてのテストコードは公式のページを参照してください。
https://laravel.com/docs/11.x/database-testing
この記事ではテスト用の環境を作成することを優先しているため、Laravel公式の会員登録機能をまとめた Jetstreamで作成されるテストコードで確認します。
# jetstreamの設定
$ composer require laravel/jetstream
$ php artisan jetstream:install livewire
# この段階でテストを実行するとデータベースファイルが存在しないエラーになります
$ php artisan test
Database file at path [/path/to/example-app/database/database.testing.sqlite] does not exist.
sqliteで設定したデータベースファイルが存在しないので作成と、マイグレーションの実行をします。
コマンドラインで実行する際には --env=testing
を使用することで .env.testing
のファイルを読み込んでからコマンドの処理を実行します。
$ php artisan migrate --env=testing
WARN The SQLite database configured for this application does not exist: database/database.testing.sqlite.
Would you like to create it? (yes/no) [yes]
❯ yes
INFO Preparing database.
Creating migration table ............................................................................................................. 6.25ms DONE
INFO Running migrations.
0001_01_01_000000_create_users_table ................................................................................................. 5.20ms DONE
0001_01_01_000001_create_cache_table ................................................................................................. 1.40ms DONE
0001_01_01_000002_create_jobs_table .................................................................................................. 3.95ms DONE
2024_05_26_023445_add_two_factor_columns_to_users_table .............................................................................. 1.58ms DONE
2024_05_26_023458_create_personal_access_tokens_table ................................................................................ 1.84ms DONE
これでテストを実行することができます。
$ php artisan test
PASS Tests\Unit\ExampleTest
✓ that true is true
WARN Tests\Feature\ApiTokenPermissionsTest
- api token permissions can be updated → API support is not enabled. 0.11s
PASS Tests\Feature\AuthenticationTest
✓ login screen can be rendered 0.04s
✓ users can authenticate using the login screen 0.03s
✓ users can not authenticate with invalid password 0.01s
PASS Tests\Feature\BrowserSessionsTest
✓ other browser sessions can be logged out 0.03s
WARN Tests\Feature\CreateApiTokenTest
- api tokens can be created → API support is not enabled. 0.01s
PASS Tests\Feature\DeleteAccountTest
✓ user accounts can be deleted 0.02s
✓ correct password must be provided before account can be deleted 0.01s
WARN Tests\Feature\DeleteApiTokenTest
- api tokens can be deleted → API support is not enabled. 0.01s
WARN Tests\Feature\EmailVerificationTest
- email verification screen can be rendered → Email verification not enabled. 0.01s
- email can be verified → Email verification not enabled.
- email can not verified with invalid hash → Email verification not enabled.
PASS Tests\Feature\ExampleTest
✓ the application returns a successful response 0.01s
PASS Tests\Feature\PasswordConfirmationTest
✓ confirm password screen can be rendered 0.01s
✓ password can be confirmed 0.01s
✓ password is not confirmed with invalid password 0.22s
PASS Tests\Feature\PasswordResetTest
✓ reset password link screen can be rendered 0.02s
✓ reset password link can be requested 0.03s
✓ reset password screen can be rendered 0.02s
✓ password can be reset with valid token 0.02s
PASS Tests\Feature\ProfileInformationTest
✓ current profile information is available 0.02s
✓ profile information can be updated 0.01s
WARN Tests\Feature\RegistrationTest
✓ registration screen can be rendered 0.01s
- registration screen cannot be rendered if support is disabled → Registration support is enabled. 0.01s
✓ new users can register 0.01s
PASS Tests\Feature\TwoFactorAuthenticationSettingsTest
✓ two factor authentication can be enabled 0.05s
✓ recovery codes can be regenerated 0.07s
✓ two factor authentication can be disabled 0.03s
PASS Tests\Feature\UpdatePasswordTest
✓ password can be updated 0.02s
✓ current password must be correct 0.02s
✓ new passwords must match 0.02s
Tests: 7 skipped, 25 passed (46 assertions)
Duration: 0.94s
これでテスト駆動開発用のデータベースを設定することができました。あとはテストコードをプロジェクトに合わせて記述していきましょう。
テストコードを書いていると、どうしても書けない処理、解りづらい内容になってしまうかと思います。その場合にはモックを使う事で解決できるかもしれません。モックについては以下の記事で解説しています。
終わりに
以上、Laravelのテスト駆動開発をする際に必要になるPHPUnitの環境構築でした。
他にも、こちらの記事で chromium-driver が実行できるようになったので、今後はレンタルサーバー内でもLaravelDuskを実行してブラウザテストも出来るようにしていきたいですね。
参考
Laravel で PHPUnit 実行時に .env.testing を見てくれない?
https://qiita.com/shohei_ot/items/de6e2da7ac0c9741904a
コメントを残す