Zum Hauptinhalt springen

Einführung

Laravel stellt eine umfangreiche API zum Simulieren von HTTP-Anfragen und Verifizieren der Antworten bereit. Sie können damit Requests an Ihre Anwendung testen, ohne einen echten HTTP-Server zu starten.
<?php

test('die Anwendung liefert eine erfolgreiche Antwort', function () {
    $response = $this->get('/');

    $response->assertStatus(200);
});
<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_the_application_returns_a_successful_response(): void
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}
Die Methode get() sendet eine GET-Anfrage an die Anwendung; assertStatus() prüft den HTTP-Statuscode der Antwort.
Während Tests wird die CSRF-Middleware automatisch deaktiviert. Sie müssen sie im Test nicht ausdrücklich abschalten.

Anfragen erzeugen

In Tests können Sie mit den Methoden get, post, put, patch und delete Anfragen absetzen. Diese senden keine echten Netzwerkanfragen, sondern simulieren die Verarbeitung innerhalb der Anwendung. Der Rückgabewert ist eine Instanz von Illuminate\Testing\TestResponse, die zahlreiche Assertion-Methoden bietet.
<?php

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

    $response->assertStatus(200);
});
<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_a_basic_request(): void
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}
Innerhalb einer Testmethode sollten Sie grundsätzlich nur eine Anfrage senden. Mehrere Anfragen in derselben Testmethode können zu unerwartetem Verhalten führen.

Request-Header anpassen

Mit withHeaders() passen Sie die Header einer Anfrage an.
<?php

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

    $response->assertStatus(201);
});
<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_interacting_with_headers(): void
    {
        $response = $this->withHeaders([
            'X-Header' => 'Value',
        ])->post('/user', ['name' => 'Sally']);

        $response->assertStatus(201);
    }
}

Cookies

Mit withCookie() bzw. withCookies() setzen Sie Cookie-Werte vor einer Anfrage.
<?php

test('Anfrage mit Cookies', function () {
    $response = $this->withCookie('color', 'blue')->get('/');

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

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_interacting_with_cookies(): void
    {
        $response = $this->withCookie('color', 'blue')->get('/');

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

Session und Authentifizierung

Mit withSession() legen Sie Session-Werte vor einer Anfrage fest.
<?php

test('Anfrage mit Session', function () {
    $response = $this->withSession(['banned' => false])->get('/');
});
<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_interacting_with_the_session(): void
    {
        $response = $this->withSession(['banned' => false])->get('/');
    }
}
Mit actingAs() versenden Sie Anfragen als authentifizierter Nutzer. Häufig in Kombination mit Model-Factories.
<?php

use App\Models\User;

test('Aktion, die eine Authentifizierung erfordert', function () {
    $user = User::factory()->create();

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

namespace Tests\Feature;

use App\Models\User;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_an_action_that_requires_authentication(): void
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)
            ->withSession(['banned' => false])
            ->get('/');
    }
}
Als zweiter Parameter kann der Guard-Name übergeben werden. Dieser wird für die Dauer des Tests zum Standard.
$this->actingAs($user, 'web');
Für Anfragen ohne Authentifizierung verwenden Sie actingAsGuest().
$this->actingAsGuest();

Antwort debuggen

Um während des Tests den Inhalt einer Antwort zu prüfen, nutzen Sie dump, dumpHeaders und dumpSession.
<?php

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

    $response->dump();
    $response->dumpHeaders();
    $response->dumpSession();
});
<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_debug_response(): void
    {
        $response = $this->get('/');

        $response->dump();
        $response->dumpHeaders();
        $response->dumpSession();
    }
}
Um die Ausführung zu stoppen, verwenden Sie dd, ddHeaders, ddBody, ddJson oder ddSession.
$response->dd();
$response->ddHeaders();
$response->ddBody();
$response->ddJson();
$response->ddSession();

Ausnahmen testen

Um zu prüfen, dass eine bestimmte Ausnahme ausgelöst wird, nutzen Sie die Facade Exceptions.
<?php

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

test('Ausnahme wird ausgelöst', function () {
    Exceptions::fake();

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

    // Prüfen, dass die Ausnahme ausgelöst wurde
    Exceptions::assertReported(InvalidOrderException::class);

    // Inhalt der Ausnahme prüfen
    Exceptions::assertReported(function (InvalidOrderException $e) {
        return $e->getMessage() === 'The order was invalid.';
    });
});
<?php

namespace Tests\Feature;

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

class ExampleTest extends TestCase
{
    public function test_exception_is_thrown(): void
    {
        Exceptions::fake();

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

        Exceptions::assertReported(InvalidOrderException::class);

        Exceptions::assertReported(function (InvalidOrderException $e) {
            return $e->getMessage() === 'The order was invalid.';
        });
    }
}
Um sicherzustellen, dass keine Ausnahme ausgelöst wurde, verwenden Sie assertNotReported oder assertNothingReported.
Exceptions::assertNotReported(InvalidOrderException::class);

Exceptions::assertNothingReported();
Um die Ausnahmebehandlung für eine Anfrage abzuschalten, nutzen Sie withoutExceptionHandling().
$response = $this->withoutExceptionHandling()->get('/');
Um zu prüfen, dass Code in einer Closure eine Ausnahme wirft, verwenden Sie assertThrows().
$this->assertThrows(
    fn () => (new ProcessOrder)->execute(),
    OrderInvalid::class
);

// Inhalt der Ausnahme prüfen
$this->assertThrows(
    fn () => (new ProcessOrder)->execute(),
    fn (OrderInvalid $e) => $e->orderId() === 123
);
Um zu prüfen, dass keine Ausnahme geworfen wird, verwenden Sie assertDoesntThrow().
$this->assertDoesntThrow(fn () => (new ProcessOrder)->execute());

Tests für JSON-APIs

Für JSON-APIs bietet Laravel zahlreiche Helfer. Mit json, getJson, postJson, putJson, patchJson, deleteJson und optionsJson senden Sie JSON-Anfragen.
<?php

test('API-Anfrage senden', function () {
    $response = $this->postJson('/api/user', ['name' => 'Sally']);

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

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_making_an_api_request(): void
    {
        $response = $this->postJson('/api/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJson([
                'created' => true,
            ]);
    }
}
Auf JSON-Daten der Antwort können Sie wie auf ein Array zugreifen.
expect($response['created'])->toBeTrue();
$this->assertTrue($response['created']);
assertJson() konvertiert die Antwort in ein Array und prüft, ob das angegebene Array Teil der JSON-Antwort ist. Zusätzliche Felder in der Antwort führen nicht zum Fehlschlagen, solange das erwartete Fragment enthalten ist.

Exakte Übereinstimmung

Mit assertExactJson() prüfen Sie, dass die zurückgegebene JSON-Antwort exakt dem angegebenen Array entspricht.
<?php

test('Exakte JSON-Assertion', function () {
    $response = $this->postJson('/user', ['name' => 'Sally']);

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

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_asserting_an_exact_json_match(): void
    {
        $response = $this->postJson('/user', ['name' => 'Sally']);

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

Werte per JSON-Pfad prüfen

Mit assertJsonPath() prüfen Sie den Wert an einem bestimmten Pfad.
<?php

test('JSON-Pfad prüfen', function () {
    $response = $this->postJson('/user', ['name' => 'Sally']);

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

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_asserting_a_json_paths_value(): void
    {
        $response = $this->postJson('/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJsonPath('team.owner.name', 'Darian');
    }
}
Über eine Closure lässt sich der Wert flexibler prüfen.
$response->assertJsonPath('team.owner.name', fn (string $name) => strlen($name) >= 3);

Fluent JSON-Tests

Wird assertJson() eine Closure übergeben, können Sie Assertions per AssertableJson verkettet formulieren.
use Illuminate\Testing\Fluent\AssertableJson;

test('Fluent JSON-Test', 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('[email protected]'))
                ->whereNot('status', 'pending')
                ->missing('password')
                ->etc()
        );
});
use Illuminate\Testing\Fluent\AssertableJson;

public function test_fluent_json(): void
{
    $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('[email protected]'))
                ->whereNot('status', 'pending')
                ->missing('password')
                ->etc()
        );
}
etc() erlaubt zusätzliche, nicht geprüfte Felder in der Antwort. Ohne etc() schlägt der Test fehl, wenn zusätzliche Felder vorhanden sind. So verhindern Sie unbeabsichtigt in Antworten enthaltene sensible Informationen.
Vorhandensein und Nichtvorhandensein von Attributen prüfen Sie mit has() und missing().
$response->assertJson(fn (AssertableJson $json) =>
    $json->has('data')
        ->missing('message')
);
Für mehrere Attribute stehen hasAll() und missingAll() bereit.
$response->assertJson(fn (AssertableJson $json) =>
    $json->hasAll(['status', 'data'])
        ->missingAll(['message', 'code'])
);

JSON-Collections prüfen

Liefert die Route mehrere Elemente, prüfen Sie Anzahl und Inhalt mit has().
$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->has(3)
            ->first(fn (AssertableJson $json) =>
                $json->where('id', 1)
                    ->where('name', 'Victoria Faith')
                    ->missing('password')
                    ->etc()
            )
    );
Um dieselbe Prüfung auf jedes Element anzuwenden, nutzen Sie each().
$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()
            )
    );

JSON-Typen prüfen

Mit whereType() und whereAllType() prüfen Sie den Datentyp einer Property.
$response->assertJson(fn (AssertableJson $json) =>
    $json->whereType('id', 'integer')
        ->whereAllType([
            'users.0.name' => 'string',
            'meta' => 'array'
        ])
);
Mit | können Sie mehrere Typen angeben; eine Übereinstimmung genügt.
$response->assertJson(fn (AssertableJson $json) =>
    $json->whereType('name', 'string|null')
        ->whereType('id', ['string', 'integer'])
);
Verfügbare Typen: string, integer, double, boolean, array, null.

Auth-Tests

Mit actingAs() senden Sie Anfragen als authentifizierter Nutzer.
<?php

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('authentifizierte Nutzer sehen das Dashboard', function () {
    $user = User::factory()->create();

    $response = $this->actingAs($user)->get('/dashboard');

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

test('nicht authentifizierte Nutzer werden weitergeleitet', function () {
    $response = $this->get('/dashboard');

    $response->assertRedirect('/login');
});
<?php

namespace Tests\Feature;

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class DashboardTest extends TestCase
{
    use RefreshDatabase;

    public function test_authenticated_users_can_view_the_dashboard(): void
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->get('/dashboard');

        $response->assertStatus(200);
    }

    public function test_unauthenticated_users_are_redirected(): void
    {
        $response = $this->get('/dashboard');

        $response->assertRedirect('/login');
    }
}
Für einen bestimmten Guard geben Sie den Namen als zweites Argument an.
$this->actingAs($user, 'api');

Beispiel: Registrierungsprozess testen

Beispiel für den Test eines realen Registrierungs-Endpunkts.
<?php

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('ein Nutzer kann sich registrieren', function () {
    $response = $this->post('/register', [
        'name'                  => 'Test User',
        'email'                 => '[email protected]',
        'password'              => 'password',
        'password_confirmation' => 'password',
    ]);

    $response->assertRedirect('/dashboard');
    $this->assertDatabaseHas('users', ['email' => '[email protected]']);
});

test('doppelte E-Mail führt nicht zur Registrierung', function () {
    User::factory()->create(['email' => '[email protected]']);

    $response = $this->post('/register', [
        'name'                  => 'Test User',
        'email'                 => '[email protected]',
        'password'              => 'password',
        'password_confirmation' => 'password',
    ]);

    $response->assertSessionHasErrors('email');
});
<?php

namespace Tests\Feature;

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class RegistrationTest extends TestCase
{
    use RefreshDatabase;

    public function test_user_can_register(): void
    {
        $response = $this->post('/register', [
            'name'                  => 'Test User',
            'email'                 => '[email protected]',
            'password'              => 'password',
            'password_confirmation' => 'password',
        ]);

        $response->assertRedirect('/dashboard');
        $this->assertDatabaseHas('users', ['email' => '[email protected]']);
    }

    public function test_duplicate_email_cannot_register(): void
    {
        User::factory()->create(['email' => '[email protected]']);

        $response = $this->post('/register', [
            'name'                  => 'Test User',
            'email'                 => '[email protected]',
            'password'              => 'password',
            'password_confirmation' => 'password',
        ]);

        $response->assertSessionHasErrors('email');
    }
}

Session-Tests

Mit withSession() setzen Sie Session-Daten vor der Anfrage; mit assertSessionHas() prüfen Sie deren Vorhandensein.
<?php

test('Session-Wert prüfen', function () {
    $response = $this->withSession(['locale' => 'de'])->get('/');

    $response->assertSessionHas('locale', 'de');
});
<?php

namespace Tests\Feature;

use Tests\TestCase;

class SessionTest extends TestCase
{
    public function test_session_value(): void
    {
        $response = $this->withSession(['locale' => 'de'])->get('/');

        $response->assertSessionHas('locale', 'de');
    }
}

Übersicht der Session-Assertions

MethodeBeschreibung
assertSessionHas($key, $value)Session enthält den Schlüssel mit dem angegebenen Wert
assertSessionHasAll([...])Session enthält mehrere Schlüssel-Wert-Paare
assertSessionHasErrors($keys)Session enthält Validierungsfehler
assertSessionHasErrorsIn($bag, $keys)Bestimmter Error-Bag enthält Fehler
assertSessionHasNoErrors()Session enthält keine Validierungsfehler
assertSessionDoesntHaveErrors()Session enthält keine Validierungsfehler
assertSessionMissing($key)Session enthält den angegebenen Schlüssel nicht

Datei-Upload-Tests

Mit Illuminate\Http\UploadedFile und der Methode fake() erzeugen Sie Dummy-Dateien und -Bilder. In Kombination mit Storage::fake() testen Sie Uploads komfortabel.
<?php

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

test('Avatar kann hochgeladen werden', function () {
    Storage::fake('avatars');

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

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

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

namespace Tests\Feature;

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

class AvatarTest extends TestCase
{
    public function test_avatars_can_be_uploaded(): void
    {
        Storage::fake('avatars');

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

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

        Storage::disk('avatars')->assertExists($file->hashName());
    }
}
Um sicherzustellen, dass eine Datei nicht existiert, nutzen Sie assertMissing().
Storage::disk('avatars')->assertMissing('missing.jpg');

Fake-Dateien anpassen

Bildgröße und Dateigröße sind einstellbar. Nützlich beim Testen von Validierungsregeln.
// Breite, Höhe und Dateigröße (in KB)
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);

// Beliebige Dateiart erzeugen
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

// MIME-Typ explizit setzen
UploadedFile::fake()->create(
    'document.pdf', $sizeInKilobytes, 'application/pdf'
);

View-Tests

Sie können Views auch direkt rendern und testen, ohne eine HTTP-Anfrage zu simulieren. Die Methode view() erwartet den View-Namen und optional ein Daten-Array und liefert eine Instanz von Illuminate\Testing\TestView.
<?php

test('Welcome-View wird gerendert', function () {
    $view = $this->view('welcome', ['name' => 'Taylor']);

    $view->assertSee('Taylor');
});
<?php

namespace Tests\Feature;

use Tests\TestCase;

class ViewTest extends TestCase
{
    public function test_a_welcome_view_can_be_rendered(): void
    {
        $view = $this->view('welcome', ['name' => 'Taylor']);

        $view->assertSee('Taylor');
    }
}
Für die TestView-Klasse stehen folgende Assertions bereit.
MethodeBeschreibung
assertSee($value)View enthält den angegebenen Text
assertSeeInOrder([...])View enthält die angegebenen Texte in dieser Reihenfolge
assertSeeText($value)Der Text der View enthält den angegebenen Text
assertSeeTextInOrder([...])Der Text enthält die angegebenen Texte in dieser Reihenfolge
assertDontSee($value)View enthält den Text nicht
assertDontSeeText($value)Der Text der View enthält den Text nicht
Um den gerenderten Inhalt als String zu erhalten, casten Sie die TestView-Instanz.
$contents = (string) $this->view('welcome');
Um Validierungsfehler an die View zu übergeben, nutzen Sie withViewErrors().
$view = $this->withViewErrors([
    'name' => ['Bitte geben Sie einen gültigen Namen ein.']
])->view('form');

$view->assertSee('Bitte geben Sie einen gültigen Namen ein.');

Komponenten testen

Mit blade() rendern Sie einen rohen Blade-Template-String.
$view = $this->blade(
    '<x-component :name="$name" />',
    ['name' => 'Taylor']
);

$view->assertSee('Taylor');
Mit component() rendern Sie Blade-Komponenten. Rückgabewert ist eine Illuminate\Testing\TestComponent-Instanz.
$view = $this->component(Profile::class, ['name' => 'Taylor']);

$view->assertSee('Taylor');

Übersicht der Response-Assertions

Wichtige Assertions von Illuminate\Testing\TestResponse:

HTTP-Status

MethodeBeschreibung
assertOk()200 OK
assertCreated()201 Created
assertAccepted()202 Accepted
assertNoContent($status = 204)204 No Content
assertBadRequest()400 Bad Request
assertUnauthorized()401 Unauthorized
assertForbidden()403 Forbidden
assertNotFound()404 Not Found
assertUnprocessable()422 Unprocessable Entity
assertTooManyRequests()429 Too Many Requests
assertInternalServerError()500 Internal Server Error
assertStatus($code)Angegebener Statuscode
assertSuccessful()Statuscode im 2xx-Bereich
assertClientError()Statuscode im 4xx-Bereich
assertServerError()Statuscode im 5xx-Bereich

Redirects

MethodeBeschreibung
assertRedirect($uri)Redirect zur angegebenen URI
assertRedirectContains($string)Redirect-URI enthält den angegebenen Text
assertRedirectToRoute($name, $params)Redirect zur angegebenen Route
assertRedirectToSignedRoute($name, $params)Redirect zur angegebenen signierten Route
assertRedirectBack()Redirect zur vorhergehenden URL

Inhalte

MethodeBeschreibung
assertSee($value, $escaped = true)Antwort enthält den angegebenen Text
assertSeeInOrder(array $values)Antwort enthält die Texte in der angegebenen Reihenfolge
assertSeeText($value)Der Text der Antwort enthält den angegebenen Text
assertDontSee($value)Antwort enthält den Text nicht
assertDontSeeText($value)Der Text der Antwort enthält den Text nicht
assertContent($value)Antwort-Body entspricht dem angegebenen Wert
assertDownload($filename)Antwort ist ein Download

JSON

MethodeBeschreibung
assertJson(array $data)JSON enthält die angegebenen Daten
assertExactJson(array $data)JSON entspricht exakt den angegebenen Daten
assertJsonPath($path, $value)Wert am angegebenen Pfad stimmt überein
assertJsonMissingPath($path)Angegebener Pfad existiert nicht
assertJsonStructure(array $structure)JSON hat die angegebene Struktur
assertJsonCount($count, $key)JSON am angegebenen Schlüssel hat die angegebene Anzahl Elemente
assertJsonFragment(array $data)JSON enthält das angegebene Fragment
assertJsonMissing(array $data)JSON enthält die angegebenen Daten nicht
assertJsonIsArray()JSON ist ein Array
assertJsonIsObject()JSON ist ein Objekt
assertJsonValidationErrors($keys)Enthält Validierungsfehler für die angegebenen Schlüssel
assertJsonMissingValidationErrors($keys)Enthält keine Validierungsfehler für die angegebenen Schlüssel

Header und Cookies

MethodeBeschreibung
assertHeader($headerName, $value)Header ist vorhanden
assertHeaderMissing($headerName)Header ist nicht vorhanden
assertCookie($name, $value)Cookie ist vorhanden
assertCookieExpired($name)Cookie ist abgelaufen
assertCookieMissing($name)Cookie ist nicht vorhanden
assertPlainCookie($name, $value)Unverschlüsseltes Cookie ist vorhanden

Views

MethodeBeschreibung
assertViewIs($value)Die angegebene View wurde zurückgegeben
assertViewHas($key, $value)View enthält die angegebenen Daten
assertViewHasAll(array $data)View enthält alle angegebenen Daten
assertViewMissing($key)View enthält die angegebenen Daten nicht

Validierung

MethodeBeschreibung
assertValid($keys)Keine Validierungsfehler für die angegebenen Schlüssel
assertInvalid($keys)Validierungsfehler für die angegebenen Schlüssel

Hinweise zu TDD

HTTP-Tests harmonieren hervorragend mit TDD (Test-Driven Development). Die folgenden Hinweise helfen Ihnen dabei.
Legen Sie HTTP-Tests im Verzeichnis tests/Feature/ an. Wer das Verhalten aus Sicht des Aufrufers (Request → Response) zuerst definiert, macht auch die zu implementierende Funktion klarer.
Nutzen Sie in Tests, die die Datenbank verwenden, das Trait RefreshDatabase. So wird die Datenbank nach jedem Test zurückgesetzt, und Tests bleiben voneinander isoliert. Das führt zu einem Testset, das unabhängig von der Ausführungsreihenfolge stabil ist.
Mit Model-Factories wie User::factory()->create() erzeugen Sie Testdaten mit wenig Code. Definieren Sie States, um bestimmte Zustände wiederverwendbar bereitzustellen – das erhöht die Lesbarkeit Ihrer Tests.
Prüfen Sie in einer Testmethode möglichst nur eine Sache. Fehler lassen sich dann schneller zuordnen. Das AAA-Muster (Arrange → Act → Assert) erleichtert das Lesen.
Für Routen mit Authentifizierung immer sowohl den authentifizierten als auch den nicht authentifizierten Fall testen. So finden Sie Sicherheitsprobleme frühzeitig.

Verwandte Seiten

Einführung in Tests

Grundlagen zum Schreiben von Tests in Laravel und zur Nutzung von php artisan test.
Zuletzt geändert am 13. Juli 2026