メインコンテンツへスキップ

はじめに

Laravelには、データベースを使う機能を安全かつ高速に検証するための仕組みが標準で用意されています。データベースリセット用トレイト、モデルファクトリ、シーダー、専用アサーションを組み合わせることで、壊れにくいテストを作成できます。 まずは RefreshDatabase を使うのが基本です。多くのケースで、完全リセットより高速にテストの独立性を保てます。

各テスト後のデータベースリセット

前のテストデータが次のテストに影響しないように、Laravelのデータベースリセット用トレイトを利用します。
<?php

use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('基本例', function () {
    $response = $this->get('/');

    $response->assertOk();
});
RefreshDatabase は、スキーマが最新かどうかを判定します。最新ならトランザクションでテストを実行し、最新でなければ先にマイグレーションを実行します。 トランザクション方式ではなく、毎回完全にリセットしたい場合は次のトレイトを使います。
トレイト挙動使いどころ
RefreshDatabaseスキーマが最新ならトランザクション、必要時のみマイグレーション通常はこれを第一候補にする
DatabaseMigrations各テストごとにマイグレーションを実行毎回マイグレーションのライフサイクルを通したい場合
DatabaseTruncationテーブルをTRUNCATEして初期化トランザクションが適さない環境で全件クリアしたい場合

モデルファクトリ

テスト前にデータを準備する際、モデルファクトリを使うとEloquentモデルを簡潔に生成できます。 ファクトリ定義・state・リレーションの詳細は Eloquentファクトリ を参照してください。
<?php

use App\Models\User;

test('モデルを生成できる', function () {
    $user = User::factory()->create();

    expect($user->exists)->toBeTrue();
});

シーダーの実行

テスト中にデータを投入したい場合は seed() を使います。引数なしなら DatabaseSeeder、引数ありなら特定シーダー(または配列)を実行できます。
<?php

use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('注文を作成できる', function () {
    $this->seed();

    $this->seed(OrderStatusSeeder::class);

    $this->seed([
        OrderStatusSeeder::class,
        TransactionStatusSeeder::class,
    ]);

    // ...
});
RefreshDatabase を使う全テストで毎回自動シードしたい場合は、基底のテストクラスに #[Seed] 属性を付けます。
<?php

namespace Tests;

use Illuminate\Foundation\Testing\Attributes\Seed;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

#[Seed]
abstract class TestCase extends BaseTestCase
{
}
特定シーダーのみを自動実行したい場合は #[Seeder(...)] を使います。
<?php

namespace Tests\Feature;

use Database\Seeders\OrderStatusSeeder;
use Illuminate\Foundation\Testing\Attributes\Seeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

#[Seeder(OrderStatusSeeder::class)]
class OrderStatusTest extends TestCase
{
    use RefreshDatabase;
}

利用可能なアサーション

Laravelには、Pest / PHPUnitのどちらでも使えるデータベース専用アサーションが用意されています。

assertDatabaseCount

テーブル内のレコード件数が期待値と一致することを確認します。
$this->assertDatabaseCount('users', 5);

assertDatabaseEmpty

テーブルが空であることを確認します。
$this->assertDatabaseEmpty('users');

assertDatabaseHas

指定した条件に一致するレコードが存在することを確認します。
$this->assertDatabaseHas('users', [
    'email' => '[email protected]',
]);

assertDatabaseMissing

指定した条件に一致するレコードが存在しないことを確認します。
$this->assertDatabaseMissing('users', [
    'email' => '[email protected]',
]);

assertSoftDeleted

対象のEloquentモデルがソフトデリート済みであることを確認します。
$this->assertSoftDeleted($user);

assertNotSoftDeleted

対象のEloquentモデルがソフトデリートされていないことを確認します。
$this->assertNotSoftDeleted($user);

assertModelExists

指定したモデル(またはモデルコレクション)がDB上に存在することを確認します。
<?php

use App\Models\User;

$user = User::factory()->create();

$this->assertModelExists($user);

assertModelMissing

指定したモデル(またはモデルコレクション)がDB上に存在しないことを確認します。
<?php

use App\Models\User;

$user = User::factory()->create();
$user->delete();

$this->assertModelMissing($user);

expectsDatabaseQueryCount

テスト冒頭で、実行されるデータベースクエリの総数を厳密に指定します。実際の実行回数が一致しない場合は失敗します。
$this->expectsDatabaseQueryCount(5);

// Test...
最終更新日 2026年5月29日