【Laravel】PHPUnitでの基本的なテスト構文
LaravelでPHPUnitを使用した際の基本的な書き方について
学んだことを備忘録として残します。
環境
- PHP 8.2.7
- Laravel 10.22.0
- PHPUnit 10.3.3
テスト実行
# すべてのテストを実行
php artisan test
# 特定のクラスやメソッド名を部分一致で指定
php artisan test --filter=testRegisterTask
# 特定のファイルを指定
php artisan test tests/Feature/TaskControllerTest.php
# 特定のフォルダを指定
php artisan test tests/Feature
実行結果例
PASS Tests\Feature\TaskControllerTest
✓ register task 0.06s
Tests: 1 passed (3 assertions)
Duration: 1.50s
OK (1 test, 3 assertions)
とは、テストが書かれたクラスが一つで
合計3つのアサーション(assertion)を実行したという意味です。
※assertionは、一つ一つの実際のテスト内容のことを指します。
命名規則
クラス名
PHPUnitはコマンド実行時にクラス名がTest
で終えるクラスを読み込むため、
テストコードのクラス名はTaskTest.php
など、必ず末尾がTest
になっている必要があります。
メソッド名
PHPUnitはtest
で始まるメソッドを実行するため、
それに合わせてメソッド名を記載する必要があります。
public function testRegisterTask(): void
{
// ...
}
もしくは、@test
というアノテーションをメソッドのDocBlockに記述することで、
メソッド名がtest
で始まらない場合でも、メソッドを実行できます。
/**
* @test
*/
public function registerTask(): void
{
// ...
}
構文
テスト時の最初と最後に実行されるメソッド
setUp()
setUp()
は、各テストメソッドに対して最初に実行されるメソッドです。
例えば以下のように、認証が必要な場合のテストに有用なactingAs
メソッドを実行し、
全てのテストメソッドでログイン状態を維持することができます。
// テストメソッド毎に最初に実行される
public function setup(): void
{
parent::setUp();
// ユーザーデータを一つ作る
$user = User::factory()->create();
// ログインした状態にする
$this->actingAs($user);
}
tearDown()
反対に、tearDown()
は各テストメソッドに対して最後に実行されます。
// テストメソッド毎に最後に実行される
protected function tearDown(): void
{
parent::tearDown();
}
テストデータをリセット
RefreshDatabase
は、テスト開始時に一度だけデータベースをリセットし、
各メソッドで実行されたテストデータをリセット(ロールバック)します。
これを使用することで、各テストは独立して実行され
テストが他のテストメソッドに影響を与えずに行うことができます。
use Illuminate\Foundation\Testing\RefreshDatabase;
class TaskTest extends TestCase
{
// テスト時にDBをリセット
use RefreshDatabase;
public function setup(): void
{
}
}
ステータスコード関連
以下はステータスコードをチェックする例です。
// 指定したステータスコードかどうか
$response->assertStatus(200);
// 200かどうか
$response->assertOk();
// 201かどうか
$response->assertCreated();
// 401かどうか
$response->assertUnauthorized();
// 403かどうか
$response->assertForbidden();
// 404かどうか
$response->assertNotFound();
// 422(validationエラー)かどうか
$response->assertUnprocessable();
データベース関連
データベースに関連するテストでは、特定のテーブルにデータが
正しく保存されているかなどを確認します。
以下は、データベース関連のアサーション例です。
// データベースに登録・更新された値が期待した通りかどうか
$this->assertDatabaseHas('tasks', [
'title' => $title,
'body' => $body,
]);
// テーブルに指定したデータが存在しないか
$this->assertDatabaseMissing('tasks', [
'title' => 'not-existing-title',
]);
// データベースのレコード数が期待値と一致するか
$recordCount = DB::table('tasks')->count();
$this->assertDatabaseCount('tasks', $recordCount);
// データベースのレコードが指定数より多いかどうか
$this->assertTrue($recordCount > 5);
// データベースのレコードが指定数より少ないかどうか
$this->assertTrue($recordCount < 10);
参考
Discussion