教材の内容に関係のない質問や教材とは異なる環境・バージョンで進めている場合のエラーなど、教材に関係しない質問は推奨していないため回答できない場合がございます。
その場合、teratailなどの外部サイトを利用して質問することをおすすめします。教材の誤字脱字や追記・改善の要望は「文章の間違いや改善点の指摘」からお願いします。
Laravel は PHPUnit を拡張して組み込んでいます。また、テストを楽にするためのいくつかの便利な機能を提供しているので、実際に手を動かす前に、どんな方針で、どんな機能を使えばいいか、といった Laravel でのテストの作り方の基礎を学びます。
Laravel をインストールすると tests ディレクトリ以下に Unit と Feature というディレクトリが予め作られています。それぞれユニットテスト用、フィーチャーテスト用のディレクトリです。
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.php1234567 Copied!<?php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
class ExampleTest extends TestCase
tests/Feature/ExampleTest.php
tests/Feature/ExampleTest.php12345678 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
に変更してください。
8 以降
php1 Copied!$user = User::factory()->create();
8 未満
php1 Copied!$user = factory(User::class)->create();
後の章でもう少し詳しく解説しますが、フィーチャーテストでデータベースにレコードが必要な場合、モデルファクトリを使ってデータを登録します。
php12 Copied!$user = User::factory()->create();
$this->actingAs($user);
ログインした状態でないとアクセスできないページ・API のテストをする際は、 actingAs
メソッドを使って、認証済みの状態にします。
RefreshDatabase
や DatabaseTransactions
といったトレイトが用意されており、各テストケースを実行後、データベースを実行前の状態に戻します。
基本的には前者を使えばいいと思いますが、前者はテスト開始時に artisan migrate:fresh --seed
を実行するのと同等なので、テスト用のデータベースを必ず用意してください(開発用のデータベースを共用していると、テスト実行時にデータが消えてしまいます)。
主にフィーチャーテスト用のアサーションが追加になっています。
すべては紹介しませんが、よく使う HTTP レスポンス(HTML、JSON)のアサーションとデータベースのアサーションについて見ていきます。
php12 Copied!$response = $this->get('/');
$response->assertStatus(200); // $this->assertSame(200, $response->getStatusCode())
php123 Copied!$response = $this->get('/');
$response->assertSee('<h1>タイトル</h1>');
$response->assertSeeText('タイトル'); // タグ以外からマッチする文字列を探す
php1234 Copied!$response = $this->get('/');
$response->assertViewIs('welcome'); // View のテンプレートパスをチェック
$response->assertViewHas('data'); // View に変数が渡っているかをチェック
$response->assertViewHas('data', [1, 2, 3]); // View に渡された変数が正しいかどうかをチェック
php12345678910 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']); // キーのみをチェック
php1234567 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
クラスと関連するトレイトのソースコードを読んでみてください。