カテゴリー
サインイン 新規登録

間違いや改善の指摘

内容の技術的な誤り・誤字脱字やミスのご報告・解説やトピックの追記/改善のご要望は教材をさらに良くしていく上でとても貴重なご意見になります。

少しでも気になった点があれば、ご遠慮なく投稿いただけると幸いです🙏

実際には誤りではなく勘違いであっても、ご報告いただけることで教材のブラッシュアップにつながります。

質問ポリシー①

教材受講者みなさんのスムーズな問題解決のために、心がけていただきたいことがあります。

教材の内容に関する質問を投稿しましょう

教材の内容に関係のない質問や教材とは異なる環境・バージョンで進めている場合のエラーなど、教材に関係しない質問は推奨していないため回答できない場合がございます。

その場合、teratailなどの外部サイトを利用して質問することをおすすめします。教材の誤字脱字や追記・改善の要望は「文章の間違いや改善点の指摘」からお願いします。

1-2

Laravel アプリケーションにおけるテストの基本的な考え方

Laravel アプリケーションにおけるテストの基本的な考え方

Laravel は PHPUnit を拡張して組み込んでいます。また、テストを楽にするためのいくつかの便利な機能を提供しているので、実際に手を動かす前に、どんな方針で、どんな機能を使えばいいか、といった Laravel でのテストの作り方の基礎を学びます。

ユニットテストとフィーチャーテストの扱い

Laravel をインストールすると tests ディレクトリ以下に UnitFeature というディレクトリが予め作られています。それぞれユニットテスト用、フィーチャーテスト用のディレクトリです。

PHPUnit で使うテストクラスを作るときは、通常 PHPUnit\Framework\TestCase というクラスを継承して作りますが、Laravel ではこのクラスを継承して独自の基底クラスを提供しています。

tests/TestCase.php を開いてください。CreatesApplication トレイトを使って、App\Console\Kernel::bootstrap() を呼び出しています。これにより、Facade の登録やコンフィグファイルの読み込みなどが行われます。つまり、Tests\TestCase クラスを継承することで Laravel の内部の機能にアクセスできるようになります。

これを踏まえて、tests/Unit/ExampleTest.php と tests/Feature/ExampleTest.php を開いてみてください。

tests/Unit/ExampleTest.php

tests/Unit/ExampleTest.php
1234567
Copied!
<?php namespace Tests\Unit; use PHPUnit\Framework\TestCase; class ExampleTest extends TestCase

tests/Feature/ExampleTest.php

tests/Feature/ExampleTest.php
12345678
Copied!
<?php namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class ExampleTest extends TestCase

Tests\TestCase を継承しているのは Feature のほうだけで、Unit にあるほうは PHPUnit が提供している基底クラスを継承しています。

これは、ユニットテストはフレームワークの機能に依存しない形で書くことが望ましい、という考え方に基づいています。

本教材でも基本的にこの方針でユニットテストを書くようにしますが、これはあくまで原則であって、フレームワークの機能(たとえば Facade など)を利用したユニットテストを書きたい場合は、継承元のクラスを Tests\TestCase に変更してください。

Laravel アプリケーションにおけるテストの特徴

モデルファクトリ

モデルファクトリは 8.0 以降と未満で記述方法に違いがありますので、お使いのバージョンに合わせた方法で記述してください(これ以降は 8.0 以上の書き方で統一します)。

8 以降

php
1
Copied!
$user = User::factory()->create();

8 未満

php
1
Copied!
$user = factory(User::class)->create();

後の章でもう少し詳しく解説しますが、フィーチャーテストでデータベースにレコードが必要な場合、モデルファクトリを使ってデータを登録します。

認証

php
12
Copied!
$user = User::factory()->create(); $this->actingAs($user);

ログインした状態でないとアクセスできないページ・API のテストをする際は、 actingAs メソッドを使って、認証済みの状態にします。

データベースのロールバック

RefreshDatabaseDatabaseTransactions といったトレイトが用意されており、各テストケースを実行後、データベースを実行前の状態に戻します。

基本的には前者を使えばいいと思いますが、前者はテスト開始時に artisan migrate:fresh --seed を実行するのと同等なので、テスト用のデータベースを必ず用意してください(開発用のデータベースを共用していると、テスト実行時にデータが消えてしまいます)。

Laravel によって追加されたアサーションメソッド

主にフィーチャーテスト用のアサーションが追加になっています。

すべては紹介しませんが、よく使う HTTP レスポンス(HTML、JSON)のアサーションとデータベースのアサーションについて見ていきます。

assertStatus / assertOk / assertCreated etc.

php
12
Copied!
$response = $this->get('/'); $response->assertStatus(200); // $this->assertSame(200, $response->getStatusCode())

assertSee / assertSeeText

php
123
Copied!
$response = $this->get('/'); $response->assertSee('<h1>タイトル</h1>'); $response->assertSeeText('タイトル'); // タグ以外からマッチする文字列を探す

assertView / assertViewHas

php
1234
Copied!
$response = $this->get('/'); $response->assertViewIs('welcome'); // View のテンプレートパスをチェック $response->assertViewHas('data'); // View に変数が渡っているかをチェック $response->assertViewHas('data', [1, 2, 3]); // View に渡された変数が正しいかどうかをチェック

assertJson / assertJsonStructure

php
12345678910
Copied!
$response = $this->getJson('/api/users'); $expectedUsers = [ ['id' => 1, 'name' => 'John Lennon'], ['id' => 2, 'name' => 'Paul McCartney'], //... ]; $response->assertJson($expectedUsers); // 値をチェック $response = $this->getJson('/api/users/1'); $response->assertJsonStructure(['id', 'name']); // キーのみをチェック

assertDatabaseHas / assertDatabaseMissing

php
1234567
Copied!
$params = ['name' => 'George Harrison', 'email' => 'gharrison@example.com']; $response = $this->postJson('/api/users', $params); // ユーザーを作成する API $user = $response->json(); $this->assertDatabaseHas('users', ['id' => $user['id']] + $params); // データが存在することをチェック $response = $this->deleteJson("/api/users/{$id}"); // ユーザーを削除する API $this->assertDatabaseMissing('access_tokens', ['id' => $id]); // データが存在しないことをチェック

本節では、Laravel がどのように PHPUnit を組み込み、拡張しているかについて解説しました。他にもテストのための便利な機能やアサーションがありますので、興味のある方は Illuminate\Foundation\Testing\TestCase クラスと関連するトレイトのソースコードを読んでみてください。