Laravelでのユーザー認証は私のブログの中では最も人気のあるトピックです。今回は、私のLaravelの日本語のレポジトリ(Laravel 5.4)のコードをもとに、ユーザー認証のテストに取り組んでいきます。
テストの種類
テストと言っても、いくつか種類があり、Laravel5.4からはtestsのディレクトリ構造も変わり、
tests ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit └── ExampleTest.php
のようにFeatureとUnitの2つのサブディレクトリができました。
Unitには、一般的にはユニットテストと呼ばれるもので、大方は画面の表示を伴わないModelのメソッドに対するテストを作成します。一方、Featureには、機能テストやアクセプタンステストとも言われ、複数のクラスの複数のメソッドが関わる主にコントローラの機能を検証するためで、あたかもユーザーがテストするようなテストを作成します。
私の今までの開発では、比較的作成しやすいUnitテストが主で、Featureテストは皆無に近く、人間のテスターがその仕事を行っています。人間をFeatureテストに置き換える予定はないですが、Laravelが提供するテストの環境がFeatureテストを作成しやすくなってきているので、この機会に習得しようということです。
Laravel5.4では、Featureテストのために、2つのテストのフレームワークが提供されています。
- HTTPテスト:ブラウザを通さないエンドポイントのテスト
- ブラウザテスト(Dusk):ブラウザキットを利用したテスト
ここでは、まず、追加のパッケージのインストールも要らない、高速なHTTPテストを作成していきます。
準備
github.comにおいて以下のブランチを用意したので利用してください。
https://github.com/lotsofbytes/larajapan/tree/5.4-test
インストールは以下を参照してください。
Laravelの日本語のレポジトリ(Laravel 5.4)
設定したら、必ず以下を実行してブランチを変えてください。
$ git checkout l54-test
また、そこでは、phpunit.xmlを編集も必要です。以下を参考にしてください。
<?xml version="1.0" encoding="UTF-8"?> <phpunit backupGlobals="false" backupStaticAttributes="false" bootstrap="bootstrap/autoload.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false"> <testsuites> <testsuite name="Feature"> <directory suffix="Test.php">./tests/Feature</directory> </testsuite> <testsuite name="Unit"> <directory suffix="Test.php">./tests/Unit</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">./app</directory> </whitelist> </filter> <php> <env name="APP_ENV" value="testing"/> <env name="APP_URL" value="http://localhost"/> <env name="CACHE_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/> <env name="DB_HOST" value="localhost"/> <env name="DB_DATABASE" value="larajapan_test"/> <env name="DB_USERNAME" value="test"/> <env name="DB_PASSWORD" value="password"/> <env name="MAIL_DRIVER" value="log" /> <env name="QUEUE_DRIVER" value="sync"/> </php> </phpunit>
テストのDBは.envで設定しているものと違うDBが必要なことに注意してください。
最初のテスト
もとからあるtests/Feature/ExampleTest.phpのファイルを、LoginTest.phpと改名して以下のように編集します。
namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\WithoutMiddleware; use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseTransactions; class LoginTest extends TestCase { /** @test */ public function user_can_view_login() { $response = $this->get('login'); $response->assertStatus(200); } /** @test */ public function unauthenticated_user_cannot_view_home() { $this->get('home') ->assertRedirect('login'); } }
最初のテストuser_can_view_loginは、ログイン画面が閲覧できるかどうかのテストです。
返ってくるHTTPのステータスのコードが200なら、成功ということです。これが404(ページが見つかりません)とかだと何かがおかしいということになります。
次のテストunauthenticated_user_cannot_view_homeは、認証が必要なホームページに、認証もなしにアクセスしてみます。もちろん、アクセスできないでログイン画面にリダイレクトされるはずです。
ここ、メソッドが連結されていることに気づきましたか?
最初のテストの例のように、以下のよう2つの文に分けても書くこともできます。
$response = $this->get('home'); $response->assertRedirect('login');
これらのテストの実行ですが、Laravelのインストールにより、すでにvendorのディレクトリにphpunitのパッケージもインストールされています。
ということで、
$ vendor/bin/phpunit PHPUnit 5.7.23 by Sebastian Bergmann and contributors. ... 3 / 3 (100%) Time: 171 ms, Memory: 10.00MB OK (3 tests, 4 assertions)
と実行してテストは皆成功となります。3 testsとあるのは、app/tests/Unit/ExampleTestがあるからです。
以下のようにフィルタを書ければ、LoginTestの中のテストだけや、user_can_view_loginの1つテストだけの実行も可能です。
$ vendor/bin/phpunit --filter=LoginTest HPUnit 5.7.23 by Sebastian Bergmann and contributors. .. 2 / 2 (100%) Time: 157 ms, Memory: 10.00MB OK (2 tests, 3 assertions) $ vendor/bin/phpunit --filter=user_can_view_login PHPUnit 5.7.23 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 111 ms, Memory: 10.00MB OK (1 test, 1 assertion)メルマガ購読の申し込みはこちらから。