テスト

Inertia アプリケーションをテストする方法は数多くあります。このページでは、利用可能なツールの概要を簡単に紹介します。

エンドツーエンドテスト

JavaScript のページコンポーネントをテストする一般的な方法の 1 つは、CypressPest のようなエンドツーエンドテストツールを使用することです。これらはブラウザ自動化ツールで、ブラウザ上でアプリの実際のシミュレーションを実行できます。これらのテストは比較的遅いことで知られていますが、エンドユーザーと同じレイヤーでアプリケーションをテストするため、アプリが正しく動作しているという高い信頼性を得ることができます。また、これらのテストはブラウザ内で実行されるため、JavaScript コードも実際に実行・検証されます。

クライアントサイドのユニットテスト

ページコンポーネントをテストする別の方法として、VitestJestMocha などのクライアントサイドのユニットテストフレームワークを使用する方法があります。このアプローチでは、Node.js を使って JavaScript のページコンポーネントを独立してテストできます。

エンドポイントテスト

JavaScript のページコンポーネントをテストするだけでなく、サーバーサイドフレームワークから返される Inertia のレスポンスもテストしたくなるでしょう。そのための一般的な方法がエンドポイントテストで、アプリケーションにリクエストを送り、レスポンスを検証します。Laravel には、これらの種類のテストを実行するための ツール が用意されています。

さらにこのプロセスを簡単にするために、Inertia の Laravel アダプタは追加の HTTP テストツールを提供しています。例を見てみましょう。

php
use Inertia\Testing\AssertableInertia as Assert;

class PodcastsControllerTest extends TestCase
{
    public function test_can_view_podcast()
    {
        $this->get('/podcasts/41')
            ->assertInertia(fn (Assert $page) => $page
                ->component('Podcasts/Show')
                ->has('podcast', fn (Assert $page) => $page
                    ->where('id', $podcast->id)
                    ->where('subject', 'The Laravel Podcast')
                    ->where('description', 'The Laravel Podcast brings you Laravel and PHP development news and discussion.')
                    ->has('seasons', 4)
                    ->has('seasons.4.episodes', 21)
                    ->has('host', fn (Assert $page) => $page
                        ->where('id', 1)
                        ->where('name', 'Matt Stauffer')
                    )
                    ->has('subscribers', 7, fn (Assert $page) => $page
                        ->where('id', 2)
                        ->where('name', 'Claudio Dekker')
                        ->where('platform', 'Apple Podcasts')
                        ->etc()
                        ->missing('email')
                        ->missing('password')
                    )
                )
            );
    }
}

上記の例から分かるように、これらのアサーションメソッドを使用して、Inertia レスポンスに提供されるデータの内容を検証できます。さらに、配列データの長さを検証したり、アサーションのスコープを限定したりすることも可能です。

inertiaProps メソッドを使用すると、レスポンスで返される props を取得できます。キーを渡すことで特定のプロパティを取得でき、ネストされたプロパティは「ドット」記法で指定できます。

php
$response = $this->get('/podcasts/41');

// すべての props を返す...
$response->inertiaProps();

// 特定の prop を返す...
$response->inertiaProps('podcast');

// 「ドット」記法でネストされた prop を返す...
$response->inertiaProps('podcast.id');

次に、assertInertia メソッドと利用可能なアサーションについて詳しく見ていきましょう。まず、Inertia レスポンスにプロパティが存在することを確認するには、has メソッドを使用します。このメソッドは、PHP の isset 関数に似ていると考えることができます。

php
$response->assertInertia(fn (Assert $page) => $page
    // ルートレベルのプロパティに 7 件のアイテムがあるかを確認...
    ->has('podcasts', 7)

    // 「ドット」記法を使用してネストされたプロパティを確認...
    ->has('podcast.subscribers', 7)
);

Inertia のプロパティに指定した数のアイテムがあることを検証するには、has メソッドの第 2 引数として期待するサイズを指定します。

php
$response->assertInertia(fn (Assert $page) => $page
    // ルートレベルのプロパティに 7 件のアイテムがあるかを確認...
    ->has('podcasts', 7)

    // 「ドット」記法を使用してネストされたプロパティを確認...
    ->has('podcast.subscribers', 7)
);

has メソッドは、ネストされたプロパティに対するアサーションの繰り返しを減らすために、プロパティのスコープを設定する目的でも使用できます。

php
$response->assertInertia(fn (Assert $page) => $page
    // 単一レベルのプロパティスコープを作成...
    ->has('message', fn (Assert $page) => $page
        // 以降はメソッドチェーンを続けられます...
        ->has('subject')
        ->has('comments', 5)

        // 「ドット」記法を使用して、さらに深いスコープを作成することも可能...
        ->has('comments.0', fn (Assert $page) => $page
            ->has('body')
            ->has('files', 1)
            ->has('files.0', fn (Assert $page) => $page
                ->has('url')
            )
        )
    )
);

配列やコレクションである Inertia プロパティにスコープする場合、指定した数のアイテムが存在することを検証しつつ、最初のアイテムに自動的にスコープすることもできます。

php
$response->assertInertia(fn (Assert $page) => $page
    // コメントが 5 件あることを確認し、自動的に最初のコメントにスコープ...
    ->has('comments', 5, fn (Assert $page) => $page
        ->has('body')
        // ...
    )
);

Inertia のプロパティが期待する値を持つことを検証するには、where アサーションを使用します。

php
$response->assertInertia(fn (Assert $page) => $page
    ->has('message', fn (Assert $page) => $page
        // subject プロパティが指定したメッセージと一致することを確認...
        ->where('subject', 'This is an example message')

        // 深くネストされた値に対してもアサーション可能...
        ->where('comments.0.files.0.name', 'example-attachment.pdf')
    )
);

Inertia のテストメソッドは、スコープ内で少なくとも 1 つの prop に対して操作を行っていない場合、自動的に失敗します。これは一般的には有用ですが、外部フィードなどの信頼性の低いデータを扱う場合や、テストを簡潔に保つために意図的に触れたくないデータがある場合には問題になることがあります。そのような場合のために、etc メソッドが用意されています。

php
$response->assertInertia(fn (Assert $page) => $page
    ->has('message', fn (Assert $page) => $page
        ->has('subject')
        ->has('comments')
        ->etc()
    )
);

missing メソッドは has メソッドの正反対で、プロパティが存在しないことを保証します。このメソッドは etc メソッドと非常に相性が良いです。

php
$response->assertInertia(fn (Assert $page) => $page
    ->has('message', fn (Assert $page) => $page
        ->has('subject')
        ->missing('published_at')
        ->etc()
    )
);

パーシャルリロードのテスト

パーシャルリロード に対するアプリケーションの挙動をテストするには、reloadOnly および reloadExcept メソッドを使用できます。これらのメソッドは追加入力のリクエストを実行し、そのレスポンスに対してアサーションを行えます。

php
$response->assertInertia(fn (Assert $page) => $page
    ->has('orders')
    ->missing('statuses')
    ->reloadOnly('statuses', fn (Assert $reload) => $reload
        ->missing('orders')
        ->has('statuses', 5)
    )
);

単一の prop を文字列で渡す代わりに、reloadOnlyreloadExcept に配列として複数の prop を渡すこともできます。

遅延 props のテスト

遅延 props に対するアプリケーションの挙動をテストするには、loadDeferredProps メソッドを使用できます。このメソッドは、遅延されたプロパティを読み込むための追加入力のリクエストを実行し、そのレスポンスに対してアサーションを行えます。

php
$response->assertInertia(fn (Assert $page) => $page
    ->has('users')
    ->has('roles')
    ->missing('permissions') // 初期レスポンスには含まれない遅延 prop
    ->loadDeferredProps(fn (Assert $reload) => $reload
        ->has('permissions')
        ->where('permissions.0.name', 'edit users')
    )
);

loadDeferredProps メソッドの第 1 引数としてグループ名を渡すことで、特定の遅延 prop グループのみを読み込むこともできます。

php
$response->assertInertia(fn (Assert $page) => $page
    ->has('users')
    ->missing('teams')
    ->missing('projects')
    ->loadDeferredProps('attributes', fn (Assert $reload) => $reload
        ->has('teams', 5)
        ->has('projects')
        ->missing('permissions') // 別のグループ
    )
);

単一のグループを文字列で渡す代わりに、loadDeferredProps に配列として複数のグループを渡すこともできます。

php
$response->assertInertia(fn (Assert $page) => $page
    ->loadDeferredProps(['default', 'attributes'], fn (Assert $reload) => $reload
        ->has('permissions')
        ->has('teams')
        ->has('projects')
    )
);

フラッシュデータのテスト

Inertia レスポンス内の フラッシュデータ をテストするには、hasFlash および missingFlash メソッドを使用できます。

php
$response->assertInertia(fn (Assert $page) => $page
    // フラッシュデータが存在することを確認...
    ->hasFlash('message')

    // フラッシュデータが特定の値を持つことを確認...
    ->hasFlash('message', 'Item saved!')

    // 「ドット」記法を使用してネストされた値も指定可能...
    ->hasFlash('notification.type', 'success')

    // フラッシュデータが存在しないことを確認...
    ->missingFlash('error')
);