Was sind Tests
Tests prüfen automatisiert, ob Ihr Code so funktioniert wie erwartet.
Wenn Sie neue Features hinzufügen oder Bugs beheben, sehen Sie mit Tests schnell, ob bestehendes Verhalten beschädigt wurde.
Im Team lassen sich Änderungen dank Tests entspannter durchführen und reviewen.
Laravel bringt Test-Unterstützung von Anfang an mit – wahlweise Pest oder PHPUnit .
Nach einer Neuinstallation existieren phpunit.xml und das Verzeichnis tests/ bereits.
Pest basiert auf PHPUnit und bietet eine kompaktere, gut lesbare Syntax. Wenn Sie neu einsteigen, ist Pest eine gute Wahl.
Aufbau des Verzeichnisses tests/
tests/
├── Feature/ # Feature-Tests
│ └── ExampleTest.php
├── Unit/ # Unit-Tests
│ └── ExampleTest.php
└── TestCase.php
Feature/ – Feature-Tests. Größere Tests mit HTTP-Anfragen, die mehrere Komponenten oder API-Endpunkte prüfen. Die meisten Ihrer Tests landen hier.
Unit/ – Unit-Tests. Testen einzelne Klassen oder Methoden. Die Laravel-App wird nicht gebootet – Datenbank und andere Framework-Funktionen stehen nicht zur Verfügung.
Test erzeugen
Neue Testklassen erzeugen Sie mit make:test.
# Feature-Test (Default)
php artisan make:test TodoTest
# Unit-Test
php artisan make:test TodoTest --unit
Ergebnis: tests/Feature/TodoTest.php.
Tests ausführen
Mit php artisan test.
vendor/bin/pest oder vendor/bin/phpunit funktionieren genauso; php artisan test liefert die schönere Ausgabe.
Optionen zum Filtern:
# Nur Feature-Tests
php artisan test --testsuite=Feature
# Sofort bei erstem Fehler stoppen
php artisan test --stop-on-failure
Einfache Tests schreiben
Beispiele für einfache Assertions:
<? php
test ( 'true is true' , function () {
expect ( true ) -> toBeTrue ();
});
test ( 'string enthält Laravel' , function () {
$message = 'Hello, Laravel!' ;
expect ( $message ) -> toContain ( 'Laravel' );
});
<? php
namespace Tests\Unit ;
use PHPUnit\Framework\ TestCase ;
class ExampleTest extends TestCase
{
public function test_true_is_true () : void
{
$this -> assertTrue ( true );
}
public function test_string_contains_laravel () : void
{
$message = 'Hello, Laravel!' ;
$this -> assertStringContainsString ( 'Laravel' , $message );
}
}
Häufige Assertions
Pest PHPUnit Bedeutung expect($x)->toBe($y)$this->assertSame($y, $x)Streng identisch expect($x)->toEqual($y)$this->assertEquals($y, $x)Gleich (ohne Typprüfung) expect($x)->toBeTrue()$this->assertTrue($x)Ist true expect($x)->toBeFalse()$this->assertFalse($x)Ist false expect($x)->toBeNull()$this->assertNull($x)Ist null expect($x)->toContain($y)$this->assertStringContainsString($y, $x)Enthält expect($x)->toHaveCount($n)$this->assertCount($n, $x)Anzahl Elemente
HTTP-Tests
Laravels HTTP-Tests simulieren Requests, ohne dass ein echter HTTP-Server läuft.
Sie kommen in Feature/-Tests zum Einsatz.
Seite anzeigen
get() sendet einen GET-Request und Sie prüfen die Antwort.
<? php
test ( 'Startseite wird angezeigt' , function () {
$response = $this -> get ( '/' );
$response -> assertStatus ( 200 );
});
<? php
namespace Tests\Feature ;
use Tests\ TestCase ;
class ExampleTest extends TestCase
{
public function test_top_page_is_displayed () : void
{
$response = $this -> get ( '/' );
$response -> assertStatus ( 200 );
}
}
Beispiel: HTTP-Tests einer ToDo-App
Angenommen, Sie haben ein Todo-Modell. So testen Sie CRUD:
<? php
use App\Models\ Todo ;
use Illuminate\Foundation\Testing\ RefreshDatabase ;
uses ( RefreshDatabase :: class );
test ( 'ToDo-Liste wird angezeigt' , function () {
Todo :: factory () -> count ( 3 ) -> create ();
$response = $this -> get ( '/todos' );
$response -> assertStatus ( 200 );
$response -> assertSee ( 'Liste' );
});
test ( 'ToDo lässt sich erstellen' , function () {
$response = $this -> post ( '/todos' , [
'title' => 'Laravel lernen' ,
]);
$response -> assertRedirect ( '/todos' );
$this -> assertDatabaseHas ( 'todos' , [ 'title' => 'Laravel lernen' ]);
});
test ( 'ToDo lässt sich löschen' , function () {
$todo = Todo :: factory () -> create ();
$response = $this -> delete ( "/todos/{ $todo -> id }" );
$response -> assertRedirect ( '/todos' );
$this -> assertDatabaseMissing ( 'todos' , [ 'id' => $todo -> id ]);
});
<? php
namespace Tests\Feature ;
use App\Models\ Todo ;
use Illuminate\Foundation\Testing\ RefreshDatabase ;
use Tests\ TestCase ;
class TodoTest extends TestCase
{
use RefreshDatabase ;
public function test_todo_list_is_displayed () : void
{
Todo :: factory () -> count ( 3 ) -> create ();
$response = $this -> get ( '/todos' );
$response -> assertStatus ( 200 );
$response -> assertSee ( 'Liste' );
}
public function test_todo_can_be_created () : void
{
$response = $this -> post ( '/todos' , [
'title' => 'Laravel lernen' ,
]);
$response -> assertRedirect ( '/todos' );
$this -> assertDatabaseHas ( 'todos' , [ 'title' => 'Laravel lernen' ]);
}
public function test_todo_can_be_deleted () : void
{
$todo = Todo :: factory () -> create ();
$response = $this -> delete ( "/todos/{ $todo -> id }" );
$response -> assertRedirect ( '/todos' );
$this -> assertDatabaseMissing ( 'todos' , [ 'id' => $todo -> id ]);
}
}
Häufige Response-Assertions
Methode Bedeutung assertStatus(200)HTTP-Statuscode assertOk()Status ist 200 assertRedirect('/path')Redirect zu URL assertSee('Text')Response enthält Text assertDontSee('Text')Response enthält Text nicht assertJson([...])JSON-Response prüfen assertDatabaseHas('table', [...])Datensatz existiert assertDatabaseMissing('table', [...])Datensatz existiert nicht
Der Trait RefreshDatabase setzt die Datenbank nach jedem Test zurück, damit sich Tests nicht gegenseitig beeinflussen.
Testumgebung
phpunit.xml
Die Testumgebung konfigurieren Sie in phpunit.xml im Projekt-Root.
Standardmäßig sind Session und Cache auf array gesetzt, sodass keine Daten überleben.
< env name = "APP_ENV" value = "testing" />
< env name = "CACHE_STORE" value = "array" />
< env name = "SESSION_DRIVER" value = "array" />
Als Datenbank ist ein SQLite-In-Memory-Setup üblich:
< env name = "DB_CONNECTION" value = "sqlite" />
< env name = "DB_DATABASE" value = ":memory:" />
Datei .env.testing
Wenn Sie im Root eine .env.testing anlegen, wird sie bei Testläufen anstelle von .env geladen.
Praktisch für spezielle Testdatenbanken oder externe Dienste.
APP_ENV =testing
DB_CONNECTION =sqlite
DB_DATABASE =:memory:
Ist der Konfigurations-Cache aktiv, führen Sie vor dem Testen php artisan config:clear aus, sonst greifen alte Werte.
Parallele Testausführung
Mit --parallel verkürzen Sie Laufzeiten, indem mehrere Prozesse gleichzeitig testen.
Zuerst brianium/paratest installieren:
composer require brianium/paratest --dev
Dann:
php artisan test --parallel
Standardmäßig entstehen so viele Prozesse wie CPU-Kerne. Anzahl mit --processes steuern:
php artisan test --parallel --processes=4
Bei parallelen Tests benötigt jeder Prozess eine eigene Datenbank. RefreshDatabase in Kombination mit In-Memory-SQLite funktioniert dafür sehr gut.
Nächste Schritte
HTTP-Tests Details zu Request-Simulation, authentifizierten Tests und JSON-Assertions.
Zuletzt geändert am 13. Juli 2026