本文へ移動
Laravel Tips

HTTP テスト

テストの中でアプリにリクエストを送り、返ってきたレスポンスを確かめる方法と、使えるアサーション(確認の命令)の一覧を説明します。

HTTP テストは、アプリに「このページをください」とお願い(リクエスト)を送って、返ってきた答え(レスポンス)が正しいかを確かめるテストです。ブラウザを開いて自分で押してみる作業を、プログラムにやらせるイメージです。Laravel は、リクエストを送る命令と、答えを調べる命令(アサーション)をたくさん用意しています。

テストの置き場所や動かし方は、テストのはじめかたを先に見てください。

最初のテスト#

次は、トップページ(/)にアクセスして、ステータスコード(結果を表す番号。200 は「成功」)が 200 かを確かめるテストです。

Pest で書くとき:

php
<?php

test('the application returns a successful response', function () {
    $response = $this->get('/');

    $response->assertStatus(200);
});

PHPUnit で書くとき:

php
<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     */
    public function test_the_application_returns_a_successful_response(): void
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}

get は GET リクエストを送る命令で、assertStatus は「返ってきたステータスコードがこの番号のはず」と確かめる命令です。ほかにも、ヘッダー(リクエストやレスポンスに付く説明書き)・本文・JSON の形などを確かめる命令があります。

リクエストを送る#

リクエストを送るには、テストの中で get・post・put・patch・delete を呼びます。実際のネットワークは使わず、アプリの内側で通信のまねをします。

これらは、ふつうの Illuminate\Http\Response ではなく Illuminate\Testing\TestResponse を返します。この TestResponse に、下の「アサーションの一覧」にある確認の命令がそろっています。

php
<?php

test('basic request', function () {
    $response = $this->get('/');

    $response->assertStatus(200);
});

ふつうは、1つのテストの中では、リクエストは1回だけにします。1つのテストで何回も送ると、思わぬ動きになることがあります。

補足

テストを動かすあいだは、CSRF 対策のミドルウェアは自動で止まります。

ヘッダーを付ける#

withHeaders で、リクエストに好きなヘッダーを付けて送れます。

php
<?php

test('interacting with headers', function () {
    $response = $this->withHeaders([
        'X-Header' => 'Value',
    ])->post('/user', ['name' => 'Sally']);

    $response->assertStatus(201);
});

withCookie は名前と値を1組、withCookies は名前と値の連想配列(名前と値の組の並び)を、リクエストの前に設定します。

php
<?php

test('interacting with cookies', function () {
    $response = $this->withCookie('color', 'blue')->get('/');

    $response = $this->withCookies([
        'color' => 'blue',
        'name' => 'Taylor',
    ])->get('/');

    //
});

セッションとログイン#

セッションに、リクエストの前に値を入れておくには withSession を使います。

php
<?php

test('interacting with the session', function () {
    $response = $this->withSession(['banned' => false])->get('/');

    //
});

セッションは、ふつう「いまログインしている人」を覚えておくために使われます。そのため、ある人をログイン中にするための actingAs が用意されています。次の例は、ファクトリ(ためしのデータを作るしくみ)で作ったユーザーでログインした状態にします。

php
<?php

use App\Models\User;

test('an action that requires authentication', function () {
    $user = User::factory()->create();

    $response = $this->actingAs($user)
        ->withSession(['banned' => false])
        ->get('/');

    //
});

actingAs の2つ目の引数にガード(ログインの確かめ方の名前)を渡すと、そのガードで認証します。そのガードは、テストが終わるまで、標準のガードにもなります。

php
$this->actingAs($user, 'web');

ログインしていない状態にしたいときは actingAsGuest を使います。

php
$this->actingAsGuest();

レスポンスの中身を調べる(デバッグ)#

テストのリクエストを送ったあと、dump・dumpHeaders・dumpSession で、レスポンスの中身を画面に出して調べられます。

php
<?php

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

    $response->dump();
    $response->dumpHeaders();
    $response->dumpSession();
});

中身を出したあとにそこで止めたいときは、dd・ddHeaders・ddBody・ddJson・ddSession を使います。

php
<?php

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

    $response->dd();
    $response->ddHeaders();
    $response->ddBody();
    $response->ddJson();
    $response->ddSession();
});
命令 説明
dump レスポンスの中身を出す
dumpHeaders レスポンスのヘッダーを出す
dumpSession セッションの中身を出す
dd レスポンスの中身を出して止まる
ddHeaders ヘッダーを出して止まる
ddBody 本文を出して止まる
ddJson JSON を出して止まる
ddSession セッションの中身を出して止まる

例外(エラー)を確かめる#

アプリが特定の例外(エラーを知らせるしくみ)を出したかを確かめたいときは、Exceptions ファサードで例外の処理を「にせもの」に置きかえます(fake)。そのあと、assertReported と assertNotReported で、リクエスト中に出た例外を確かめます。

php
<?php

use App\Exceptions\InvalidOrderException;
use Illuminate\Support\Facades\Exceptions;

test('exception is thrown', function () {
    Exceptions::fake();

    $response = $this->get('/order/1');

    // 例外が出たことを確かめる
    Exceptions::assertReported(InvalidOrderException::class);

    // 例外の中身も確かめる
    Exceptions::assertReported(function (InvalidOrderException $e) {
        return $e->getMessage() === 'The order was invalid.';
    });
});

特定の例外が出ていないこと、またはどんな例外も出ていないことは、次のように確かめます。

php
Exceptions::assertNotReported(InvalidOrderException::class);

Exceptions::assertNothingReported();

あるリクエストだけ、例外の処理を完全に止めたいときは withoutExceptionHandling を使います。

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

PHP や使っているライブラリが「もう古い」としている機能(非推奨)を、アプリが使っていないかを確かめたいときは withoutDeprecationHandling を使います。これを使うと、非推奨の警告が例外に変わり、テストが失敗します。

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

クロージャの中のコードが、決めた種類の例外を出すかは assertThrows で確かめます。

php
$this->assertThrows(
    fn () => (new ProcessOrder)->execute(),
    OrderInvalid::class
);

出た例外の中身まで調べたいときは、2つ目の引数にクロージャを渡します。

php
$this->assertThrows(
    fn () => (new ProcessOrder)->execute(),
    fn (OrderInvalid $e) => $e->orderId() === 123
);

クロージャの中のコードが、例外を1つも出さないことは assertDoesntThrow で確かめます。

php
$this->assertDoesntThrow(fn () => (new ProcessOrder)->execute());

JSON の API をテストする#

JSON(データを文字で表す形式)を返す API(プログラムどうしがやり取りする窓口)をテストするときは、json・getJson・postJson・putJson・patchJson・deleteJson・optionsJson を使います。データやヘッダーも渡せます。次は、/api/user に POST で送って、期待した JSON が返るかを確かめる例です。

php
<?php

test('making an api request', function () {
    $response = $this->postJson('/api/user', ['name' => 'Sally']);

    $response
        ->assertStatus(201)
        ->assertJson([
            'created' => true,
        ]);
});

JSON の中身は、レスポンスを配列のように読んで取り出せます。

Pest のとき:

php
expect($response['created'])->toBeTrue();

PHPUnit のとき:

php
$this->assertTrue($response['created']);

補足

assertJson は、レスポンスを配列にして「渡した配列がその中にあるか」を調べます。ほかの項目が混ざっていても、渡した部分があれば成功します。

JSON がぴったり同じかを確かめる#

assertJson は一部が合っていれば通ります。渡した配列と JSON がぴったり同じかを確かめたいときは assertExactJson を使います。

php
<?php

test('asserting an exact json match', function () {
    $response = $this->postJson('/user', ['name' => 'Sally']);

    $response
        ->assertStatus(201)
        ->assertExactJson([
            'created' => true,
        ]);
});

JSON のパス(道すじ)で確かめる#

JSON の中の決まった場所に、決まった値があるかは assertJsonPath で確かめます。場所は team.owner.name のように、ドットでつないで書きます。

php
<?php

test('asserting a json path value', function () {
    $response = $this->postJson('/user', ['name' => 'Sally']);

    $response
        ->assertStatus(201)
        ->assertJsonPath('team.owner.name', 'Darian');
});

値の代わりにクロージャを渡すと、その結果で成功か失敗かを決められます。

php
$response->assertJsonPath('team.owner.name', fn (string $name) => strlen($name) >= 3);

複数の場所をまとめて確かめるには assertJsonPaths を使います。値の代わりにクロージャも書けます。

php
$response->assertJsonPaths([
    'team.owner.name' => 'Darian',
    'team.owner.email' => fn (string $email) => str($email)->is('*@laravel.com'),
    'team.members.0.name' => 'Sally',
]);

複数の場所が「無い」ことは assertJsonMissingPaths で確かめます。

php
$response->assertJsonMissingPaths([
    'team.owner.password',
    'team.members.0.api_token',
]);

流れるように JSON を確かめる(Fluent JSON テスト)#

assertJson にクロージャを渡すと、AssertableJson というオブジェクトを使って、メソッドをつないで確かめられます。where は項目の値を、missing は項目が無いことを確かめます。

php
use Illuminate\Testing\Fluent\AssertableJson;

test('fluent json', function () {
    $response = $this->getJson('/users/1');

    $response
        ->assertJson(fn (AssertableJson $json) =>
            $json->where('id', 1)
                ->where('name', 'Victoria Faith')
                ->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
                ->whereNot('status', 'pending')
                ->missing('password')
                ->etc()
        );
});

etc メソッドの意味#

上の例の最後の etc は、「JSON にはほかの項目もあってよい」と Laravel に伝える命令です。etc が無いと、確かめていない項目が JSON にあるだけでテストが失敗します。

こうなっている理由は、うっかり秘密の情報を JSON に出してしまうのを防ぐためです。「1つずつ確かめる」か「ほかの項目があってもよいと etc で言う」かを、はっきり選ばせます。

ただし、etc を付けないことは、入れ子になった配列の中に項目が増えていないことまでは守りません。etc が確かめるのは、etc を書いた階層(入れ子の段)だけです。

項目の有る・無いを確かめる#

has は項目があること、missing は無いことを確かめます。

php
$response->assertJson(fn (AssertableJson $json) =>
    $json->has('data')
        ->missing('message')
);

hasAll と missingAll は、複数の項目をまとめて確かめます。

php
$response->assertJson(fn (AssertableJson $json) =>
    $json->hasAll(['status', 'data'])
        ->missingAll(['message', 'code'])
);

hasAny は、渡した項目のうち1つでもあれば成功します。

php
$response->assertJson(fn (AssertableJson $json) =>
    $json->has('status')
        ->hasAny('data', 'message', 'code')
);

JSON の一覧(コレクション)を確かめる#

ルートが、ユーザーのような複数の項目を返すことがあります。

php
Route::get('/users', function () {
    return User::all();
});

この場合は、has に数を渡して「3件ある」と確かめられます。first は、先頭の項目だけを確かめるためのクロージャを受け取ります。

php
$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->has(3)
            ->first(fn (AssertableJson $json) =>
                $json->where('id', 1)
                    ->where('name', 'Victoria Faith')
                    ->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
                    ->missing('password')
                    ->etc()
            )
    );

すべての項目に同じ確かめをしたいときは each を使います。

php
$response
  ->assertJson(fn (AssertableJson $json) =>
      $json->has(3)
          ->each(fn (AssertableJson $json) =>
              $json->whereType('id', 'integer')
                  ->whereType('name', 'string')
                  ->whereType('email', 'string')
                  ->missing('password')
                  ->etc()
          )
  );

名前の付いた一覧を確かめる#

一覧が、名前の付いたキーの中に入って返ってくることもあります。

php
Route::get('/users', function () {
    return [
        'meta' => [...],
        'users' => User::all(),
    ];
});

has は、一覧の件数を確かめるのにも、確かめる範囲を絞るのにも使えます。

php
$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->has('meta')
            ->has('users', 3)
            ->has('users.0', fn (AssertableJson $json) =>
                $json->where('id', 1)
                    ->where('name', 'Victoria Faith')
                    ->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
                    ->missing('password')
                    ->etc()
            )
    );

has を2回呼ばなくても、3つ目の引数にクロージャを渡せば、1回で済みます。このクロージャは、一覧の先頭の項目の範囲で動きます。

php
$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->has('meta')
            ->has('users', 3, fn (AssertableJson $json) =>
                $json->where('id', 1)
                    ->where('name', 'Victoria Faith')
                    ->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
                    ->missing('password')
                    ->etc()
            )
    );

値の型を確かめる#

値そのものではなく「型」(文字列か数字かなど)だけを確かめたいときは、whereType と whereAllType を使います。

php
$response->assertJson(fn (AssertableJson $json) =>
    $json->whereType('id', 'integer')
        ->whereAllType([
            'users.0.name' => 'string',
            'meta' => 'array'
        ])
);

型を | でつなぐか、配列で渡すと、どれか1つに当てはまれば成功します。

php
$response->assertJson(fn (AssertableJson $json) =>
    $json->whereType('name', 'string|null')
        ->whereType('id', ['string', 'integer'])
);

使える型は次のとおりです。

型 説明
string 文字列
integer 整数
double 小数
boolean 真偽(true か false)
array 配列
null 値が無いこと

JSON を確かめる命令のまとめ#

命令 説明
where 項目の値が合っているか
whereNot 項目の値が、渡した値ではないか
missing 項目が無いか
missingAll 複数の項目がすべて無いか
has 項目があるか。数やクロージャも渡せる
hasAll 複数の項目がすべてあるか
hasAny 渡した項目のどれかがあるか
first 一覧の先頭の項目を確かめる
each 一覧のすべての項目を確かめる
whereType 項目の型が合っているか
whereAllType 複数の項目の型が合っているか
etc ほかの項目があってもよいと伝える

ファイルのアップロードをテストする#

Illuminate\Http\UploadedFile の fake メソッドで、テスト用のにせのファイルや画像を作れます。Storage ファサードの fake と組み合わせると、アップロードのテストが簡単になります。次は、アバター(プロフィール画像)のアップロードを確かめる例です。

php
<?php

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;

test('avatars can be uploaded', function () {
    Storage::fake('avatars');

    $file = UploadedFile::fake()->image('avatar.jpg');

    $response = $this->post('/avatar', [
        'avatar' => $file,
    ]);

    Storage::disk('avatars')->assertExists($file->hashName());
});

ファイルが「無い」ことは、Storage の assertMissing で確かめます。

php
Storage::fake('avatars');

// ...

Storage::disk('avatars')->assertMissing('missing.jpg');

にせのファイルを細かく決める#

UploadedFile の fake で画像を作るとき、幅・高さ・サイズ(キロバイト)を決められます。バリデーション(送られてきた入力が正しいかのチェック)のルールを試すときに便利です。

php
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);

画像以外のファイルは create で作ります。

php
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

必要なら、MIME タイプ(ファイルの種類を表す名前)も渡せます。

php
UploadedFile::fake()->create(
    'document.pdf', $sizeInKilobytes, 'application/pdf'
);

ビューをテストする#

リクエストを送らずに、ビュー(画面の見た目を書いたファイル)だけを作って確かめることもできます。view メソッドに、ビューの名前と、あれば渡すデータを渡します。Illuminate\Testing\TestView が返り、中身を確かめる命令が使えます。

php
<?php

test('a welcome view can be rendered', function () {
    $view = $this->view('welcome', ['name' => 'Taylor']);

    $view->assertSee('Taylor');
});

TestView で使える命令は次のとおりです。

命令 説明
assertSee 渡した文字が含まれる
assertSeeInOrder 渡した文字が、順番どおりに含まれる
assertSeeText タグを除いた文章に、渡した文字が含まれる
assertSeeTextInOrder タグを除いた文章に、渡した文字が順番どおりに含まれる
assertDontSee 渡した文字が含まれない
assertDontSeeText タグを除いた文章に、渡した文字が含まれない

TestView を文字列に変えると、できあがった HTML をそのまま取り出せます。

php
$contents = (string) $this->view('welcome');

エラーを渡す#

ビューによっては、入力チェックのエラーをまとめた入れ物(エラーバッグ)を使います。そのエラーを用意するには withViewErrors を使います。

php
$view = $this->withViewErrors([
    'name' => ['Please provide a valid name.']
])->view('form');

$view->assertSee('Please provide a valid name.');

Blade の文字やコンポーネントを描く#

blade メソッドで、Blade の文字列をそのまま描いて確かめられます。view と同じく TestView が返ります。

php
$view = $this->blade(
    '<x-component :name="$name" />',
    ['name' => 'Taylor']
);

$view->assertSee('Taylor');

Blade コンポーネントは component メソッドで描きます。こちらは Illuminate\Testing\TestComponent が返ります。

php
$view = $this->component(Profile::class, ['name' => 'Taylor']);

$view->assertSee('Taylor');

ルートをキャッシュする#

テストの前に、Laravel はアプリを新しく起動し、定義されたルートをすべて集めます。ルートのファイルが多いアプリでは、テストのクラスに Illuminate\Foundation\Testing\WithCachedRoutes トレイト(クラスに部品を足すしくみ)を足すとよいでしょう。ルートを1回だけ作ってメモリに置き、ほかのテストで使い回します。

php
<?php

use App\Http\Controllers\UserController;
use Illuminate\Foundation\Testing\WithCachedRoutes;

pest()->use(WithCachedRoutes::class);

test('basic example', function () {
    $this->get(action([UserController::class, 'index']));

    // ...
});

PHPUnit のときは、クラスの中で use WithCachedRoutes; と書きます。

php
<?php

namespace Tests\Feature;

use App\Http\Controllers\UserController;
use Illuminate\Foundation\Testing\WithCachedRoutes;
use Tests\TestCase;

class BasicTest extends TestCase
{
    use WithCachedRoutes;

    /**
     * A basic functional test example.
     */
    public function test_basic_example(): void
    {
        $response = $this->get(action([UserController::class, 'index']));

        // ...
    }
}

アサーションの一覧#

レスポンスのアサーション#

TestResponse には、たくさんの確認の命令があります。json・get・post・put・delete などが返すレスポンスに対して使います。ここでは種類ごとに分けて並べます。

ステータスコードを確かめる#

命令 説明
assertOk 200(成功)である
assertCreated 201(作成した)である
assertAccepted 202(受け付けた)である
assertNoContent 内容が無く、決めた番号(初期値は 204)である
assertMovedPermanently 301(恒久的に引っ越した)である
assertFound 302(見つかった。転送)である
assertBadRequest 400(リクエストが不正)である
assertUnauthorized 401(ログインが必要)である
assertPaymentRequired 402(支払いが必要)である
assertForbidden 403(禁止)である
assertNotFound 404(見つからない)である
assertMethodNotAllowed 405(その種類のリクエストは許されない)である
assertRequestTimeout 408(リクエストが時間切れ)である
assertConflict 409(食い違いがある)である
assertGone 410(もう無い)である
assertUnsupportedMediaType 415(対応していない種類のデータ)である
assertUnprocessable 422(処理できない内容)である
assertTooManyRequests 429(リクエストが多すぎる)である
assertInternalServerError 500(サーバーの内部エラー)である
assertServiceUnavailable 503(いまは使えない)である
assertFailedDependency 424(前提の処理に失敗した)である
assertStatus 渡した番号のステータスコードである
assertSuccessful 200 以上 300 未満(成功の仲間)である
assertClientError 400 以上 500 未満(リクエスト側の誤り)である
assertServerError 500 以上 600 未満(サーバー側の誤り)である

使い方はどれも同じです。たとえば次のように書きます。

php
$response->assertOk();
$response->assertStatus($code);
$response->assertNoContent($status = 204);
命令 説明
assertCookie 渡した名前(と値)の Cookie が含まれる
assertCookieExpired その Cookie があり、期限が切れている
assertCookieNotExpired その Cookie があり、期限が切れていない
assertCookieMissing その Cookie が含まれない
assertPlainCookie 暗号化されていない Cookie が含まれる
php
$response->assertCookie($cookieName, $value = null);
$response->assertCookieExpired($cookieName);
$response->assertCookieNotExpired($cookieName);
$response->assertCookieMissing($cookieName);
$response->assertPlainCookie($cookieName, $value = null);

本文やヘッダーを確かめる#

命令 説明
assertSee 渡した文字が含まれる。ふつうは自動でエスケープする
assertSeeInOrder 渡した文字が、順番どおりに含まれる
assertSeeText タグを除いた文章に、渡した文字が含まれる
assertSeeTextInOrder タグを除いた文章に、渡した文字が順番どおりに含まれる
assertDontSee 渡した文字が含まれない
assertDontSeeText タグを除いた文章に、渡した文字が含まれない
assertContent 本文が、渡した文字と同じである
assertHeader 渡したヘッダー(と値)がある
assertHeaderContains ヘッダーの値に、渡した文字が含まれる
assertHeaderMissing 渡したヘッダーが無い
assertDownload ダウンロードのレスポンスである
assertStreamed ストリーム(少しずつ送る形)のレスポンスである
assertStreamedContent ストリームの内容が、渡した文字と同じである

assertSee などの文字を調べる命令は、渡した文字を自動でエスケープ(HTML で特別な意味を持つ記号を、ふつうの文字に直すこと)します。2つ目の引数に false を渡すと、エスケープしません。Text が付く命令は、PHP の strip_tags でタグを取りのぞいた文章を調べます。

php
$response->assertSee($value, $escape = true);
$response->assertSeeInOrder(array $values, $escape = true);
$response->assertSeeText($value, $escape = true);
$response->assertSeeTextInOrder(array $values, $escape = true);
$response->assertDontSee($value, $escape = true);
$response->assertDontSeeText($value, $escape = true);
$response->assertContent($value);
$response->assertHeader($headerName, $value = null);
$response->assertHeaderContains($headerName, $value);
$response->assertHeaderMissing($headerName);
$response->assertStreamed();
$response->assertStreamedContent($value);

assertDownload は、レスポンスがダウンロードかを確かめます。ふつうは、ルートが Response::download・BinaryFileResponse・Storage::download のどれかを返したときです。ダウンロードのファイル名も確かめられます。

php
$response->assertDownload();

$response->assertDownload('image.jpg');

リダイレクト(転送)を確かめる#

命令 説明
assertRedirect 渡した URI への転送である
assertRedirectBack 前のページへ戻す転送である
assertRedirectBackWithErrors 前のページへ戻す転送で、セッションに渡したエラーがある
assertRedirectBackWithoutErrors 前のページへ戻す転送で、セッションにエラーが無い
assertRedirectContains 転送先の URI に、渡した文字が含まれる
assertRedirectToRoute 名前を付けたルートへの転送である
assertRedirectToSignedRoute 署名付きルート(改ざんを防ぐ印が付いた URL)への転送である
assertLocation Location ヘッダーが、渡した URI である
php
$response->assertRedirect($uri = null);
$response->assertRedirectBack();
$response->assertRedirectBackWithErrors(
    array $keys = [], $format = null, $errorBag = 'default'
);
$response->assertRedirectBackWithoutErrors();
$response->assertRedirectContains($string);
$response->assertRedirectToRoute($name, $parameters = []);
$response->assertRedirectToSignedRoute($name = null, $parameters = []);
$response->assertLocation($uri);

JSON を確かめる#

命令 説明
assertJson 渡した JSON のデータが含まれる
assertExactJson 渡した JSON のデータとぴったり同じである
assertJsonFragment 渡した JSON のデータが、どこかに含まれる
assertJsonMissing 渡した JSON のデータが含まれない
assertJsonMissingExact 渡した JSON のデータと同じものが含まれない
assertJsonCount 渡したキーの配列に、決めた数の項目がある
assertJsonIsArray JSON が配列である
assertJsonIsObject JSON がオブジェクト(名前と値の組)である
assertJsonPath 渡した場所に、期待した値がある
assertJsonPaths 渡した複数の場所に、期待した値がある
assertJsonMissingPath 渡した場所が無い
assertJsonMissingPaths 渡した複数の場所が無い
assertJsonStructure 渡した形(キーの並び)である
assertExactJsonStructure 渡した形とぴったり同じである
php
$response->assertJson(array $data, $strict = false);
$response->assertExactJson(array $data);
$response->assertJsonCount($count, $key = null);
$response->assertJsonMissing(array $data);
$response->assertJsonMissingExact(array $data);
$response->assertJsonIsArray();
$response->assertJsonIsObject();
$response->assertJsonStructure(array $structure);
$response->assertExactJsonStructure(array $data);

assertJsonFragment は、JSON のどの深さにあっても見つけます。

php
Route::get('/users', function () {
    return [
        'users' => [
            [
                'name' => 'Taylor Otwell',
            ],
        ],
    ];
});

$response->assertJsonFragment(['name' => 'Taylor Otwell']);

assertJsonPath は、場所と期待する値を渡します。たとえば、次の JSON があるとします。

json
{
    "user": {
        "name": "Steve Schoger"
    }
}

user の中の name を確かめるには、こう書きます。

php
$response->assertJsonPath('user.name', 'Steve Schoger');

複数の場所をまとめて確かめるときは assertJsonPaths を使います。

php
$response->assertJsonPaths([
    'user.name' => 'Steve Schoger',
    'user.email' => fn (string $email) => str($email)->endsWith('@laravel.com'),
]);

「無い」ことを確かめる assertJsonMissingPath と assertJsonMissingPaths は次のとおりです。

php
$response->assertJsonMissingPath('user.email');

$response->assertJsonMissingPaths([
    'user.email',
    'user.password',
]);

assertJsonStructure は、値ではなく形だけを確かめます。

php
$response->assertJsonStructure([
    'user' => [
        'name',
    ]
]);

次のように、オブジェクトの配列が返ることもあります。

json
{
    "user": [
        {
            "name": "Steve Schoger",
            "age": 55,
            "location": "Earth"
        },
        {
            "name": "Mary Schoger",
            "age": 60,
            "location": "Earth"
        }
    ]
}

そのときは * を使うと、配列の中のすべてのオブジェクトの形を確かめられます。

php
$response->assertJsonStructure([
    'user' => [
        '*' => [
             'name',
             'age',
             'location'
        ]
    ]
]);

assertExactJsonStructure は assertJsonStructure のきびしい版です。期待した形に書いていないキーがレスポンスにあると、失敗します。

セッションを確かめる#

命令 説明
assertSessionHas セッションに、渡したデータがある
assertSessionHasInput 一度だけ残した入力(フラッシュ入力)に、渡した値がある
assertSessionHasAll セッションに、渡したキーと値の組がすべてある
assertSessionMissing セッションに、渡したキーが無い
assertSessionMissingInput 一度だけ残した入力に、渡したキーが無い
php
$response->assertSessionHas($key, $value = null);
$response->assertSessionHasInput($key, $value = null);
$response->assertSessionHasAll(array $data);
$response->assertSessionMissing($key);
$response->assertSessionMissingInput($key);

assertSessionHas と assertSessionHasInput の2つ目の引数には、クロージャも渡せます。クロージャが true を返すと成功します。

php
$response->assertSessionHas($key, function (User $value) {
    return $value->name === 'Taylor Otwell';
});
php
use Illuminate\Support\Facades\Crypt;

$response->assertSessionHasInput($key, function (string $value) {
    return Crypt::decryptString($value) === 'secret';
});

assertSessionHasAll は、キーと値の組をまとめて確かめます。

php
$response->assertSessionHasAll([
    'name' => 'Taylor Otwell',
    'status' => 'active',
]);

入力チェックのエラーを確かめる#

命令 説明
assertSessionHasErrors セッションに、渡したキーのエラーがある
assertSessionHasErrorsIn 名前の付いたエラーバッグの中に、渡したキーのエラーがある
assertSessionHasNoErrors セッションに、エラーが1つも無い
assertSessionDoesntHaveErrors セッションに、渡したキーのエラーが無い
assertJsonValidationErrors JSON のエラーに、渡したキーのエラーがある
assertJsonValidationErrorFor JSON のエラーに、渡したキーのエラーが何かある
assertJsonMissingValidationErrors JSON のエラーに、渡したキーのエラーが無い
assertValid 入力チェックのエラーが無い(JSON でもセッションでも)
assertInvalid 入力チェックのエラーがある(JSON でもセッションでも)
assertOnlyInvalid 渡した項目だけにエラーがある
php
$response->assertSessionHasErrors(
    array $keys = [], $format = null, $errorBag = 'default'
);
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
$response->assertSessionHasNoErrors();
$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
$response->assertJsonValidationErrors(array $data, $responseKey = 'errors');
$response->assertJsonValidationErrorFor(string $key, $responseKey = 'errors');
$response->assertJsonMissingValidationErrors($keys);

assertSessionHasErrors は、エラーがセッションに入る画面(フォーム)で使います。JSON で返す API では使いません。

php
$response->assertSessionHasErrors(['name', 'email']);

メッセージまで確かめたいときは、キーと文を渡します。

php
$response->assertSessionHasErrors([
    'name' => 'The given name was invalid.'
]);

補足

assertSessionHasErrors と assertJsonValidationErrors は、エラーの返し方(セッションか JSON か)が決まっているときに使います。どちらでもよいときは、もっと広く使える assertInvalid がべんりです。これは、エラーが JSON で返ったときも、セッションに入ったときも調べます。逆に「エラーが無い」ことは assertValid で調べます。これは、JSON のエラーが無く、かつセッションにもエラーが入っていないことを調べます。

assertValid と assertInvalid の使い方です。

php
// 入力チェックのエラーがまったく無い
$response->assertValid();

// 渡したキーにエラーが無い
$response->assertValid(['name', 'email']);

// 渡したキーにエラーがある
$response->assertInvalid(['name', 'email']);

assertInvalid では、キーごとにメッセージも確かめられます。メッセージは全文でも、一部だけでもかまいません。

php
$response->assertInvalid([
    'name' => 'The name field is required.',
    'email' => 'valid email address',
]);

渡した項目だけにエラーがあることを確かめるときは assertOnlyInvalid を使います。

php
$response->assertOnlyInvalid(['name', 'email']);

ビューを確かめる#

命令 説明
assertViewIs ルートが、渡した名前のビューを返した
assertViewHas ビューに、渡したデータがある
assertViewHasAll ビューに、渡したデータがすべてある
assertViewMissing ビューに、渡したキーのデータが無い
php
$response->assertViewIs($value);
$response->assertViewHas($key, $value = null);
$response->assertViewHasAll(array $data);
$response->assertViewMissing($key);

assertViewHas の2つ目の引数にクロージャを渡すと、データの中身を調べられます。

php
$response->assertViewHas('user', function (User $user) {
    return $user->name === 'Taylor';
});

ビューのデータは、レスポンスを配列のように読んでも取り出せます。

Pest のとき:

php
expect($response['name'])->toBe('Taylor');

PHPUnit のとき:

php
$this->assertEquals('Taylor', $response['name']);

assertViewHasAll は、キーだけでも、キーと値の組でも確かめられます。

php
$response->assertViewHasAll([
    'name',
    'email',
]);

$response->assertViewHasAll([
    'name' => 'Taylor Otwell',
    'email' => 'taylor@example.com,',
]);

ログインのアサーション#

ログインに関する命令もあります。これらは get や post が返すレスポンスではなく、テストのクラス自身に対して呼びます($this->)。

命令 説明
assertAuthenticated ログインしている人がいる
assertGuest ログインしている人がいない
assertAuthenticatedAs 渡したユーザーがログインしている
php
$this->assertAuthenticated($guard = null);

$this->assertGuest($guard = null);

$this->assertAuthenticatedAs($user, $guard = null);

入力チェックのアサーション#

入力チェックについては、主に2つの命令があります。送ったデータが正しかったか、まちがっていたかを確かめます。

命令 説明
assertValid 渡したキーに、入力チェックのエラーが無い
assertInvalid 渡したキーに、入力チェックのエラーがある

使い方は、上の「入力チェックのエラーを確かめる」と同じです。エラーが JSON で返ったときも、セッションに入ったときも使えます。

php
// エラーがまったく無い
$response->assertValid();

// 渡したキーにエラーが無い
$response->assertValid(['name', 'email']);

// 渡したキーにエラーがある
$response->assertInvalid(['name', 'email']);

// メッセージも確かめる(全文でも一部でもよい)
$response->assertInvalid([
    'name' => 'The name field is required.',
    'email' => 'valid email address',
]);

入力チェックそのものはバリデーションを見てください。

関連するページ#

公式ドキュメント(英語)

2026年10月5日時点の内容をもとに、日本語でまとめています。

ページの一覧