Vorstellung von Pest PHP – seit Laravel 11 Standard – aus Senior-Engineer-Perspektive. Vom Unterschied zu PHPUnit über Migrationskosten bis zur Nutzung von arch()-Tests, ausgerichtet auf reale Projekteinführungen.
Seit Laravel 11 wird beim Anlegen eines Projekts mit laravel newPest als Test-Framework standardmäßig ausgewählt. PHPUnit war lange das Standard-Testtool in PHP; Pest baut darauf auf und bietet eine kürzere, besser lesbare Schreibweise.
Da Pest auf PHPUnit läuft, funktionieren bestehende PHPUnit-Tests unverändert weiter. Eine Migration lässt sich schrittweise vornehmen.
Hinter der offiziellen Wahl von Pest steht das Ziel, die Hürden beim Schreiben von Tests zu reduzieren. Rituale wie „Klasse anlegen, Methode schreiben” entfallen; die Schreibweise lässt Sie sich auf das konzentrieren, was Sie testen wollen – so entsteht die Gewohnheit, Tests zu schreiben, viel natürlicher.
test('Nutzer kann sich einloggen', function () { $user = User::factory()->create(); $response = $this->post('/login', [ 'email' => $user->email, 'password' => 'password', ]); $response->assertRedirect('/dashboard');});
class AuthTest extends TestCase{ public function test_user_can_login(): void { $user = User::factory()->create(); $response = $this->post('/login', [ 'email' => $user->email, 'password' => 'password', ]); $response->assertRedirect('/dashboard'); }}
Die test()-Funktion von Pest nimmt eine Closure entgegen. Ohne Klassen- und Methodendefinition wird die Testabsicht schon in der ersten Zeile klar. it() funktioniert analog. Auf Englisch liest sich it('can login', ...) wie ein natürlicher Satz.
Sie können Assertions in natürlicher englischer Form schreiben – expect($value)->toBe(), ->toBeNull(), ->toContain(), ->toHaveCount() – und mehrere Assertions per Method Chaining kombinieren.
arch() in Pest sind Tests, die die Struktur der Codebasis prüfen. Sie können automatisch Architekturregeln validieren wie „hängt ein Controller direkt vom Modell ab?” oder „erbt das Modell von Eloquent?”.
test('Modelle erben von Eloquent', function () { arch()->expect('App\Models') ->toExtend(Illuminate\Database\Eloquent\Model::class);});test('Controller sind final', function () { arch()->expect('App\Http\Controllers') ->toBeFinal();});test('Service-Klassen hängen nicht von Controllern ab', function () { arch()->expect('App\Services') ->not->toUse('App\Http\Controllers');});
arch()-Tests werden statisch über den Quellcode ausgeführt. Sie stellen keine echten HTTP-Requests und greifen nicht auf die Datenbank zu und sind daher sehr schnell.
Pest bringt außerdem Presets für häufig verwendete Architekturregeln mit.
test('Laravel-Architekturregeln werden befolgt', function () { arch()->preset()->laravel();});
Das Preset laravel() bündelt gebräuchliche Regeln – Modellnamen, Controller-Vererbung, Middleware-Struktur – nach Laravel-typischen Konventionen.
Da Pest von Laravels TestCase erbt, stehen actingAs(), assertDatabaseHas(), die HTTP-Test-Helfer und alle weiteren Test-Helfer unverändert zur Verfügung.
use App\Models\Post;use App\Models\User;test('Nutzer kann eigenen Beitrag löschen', function () { $user = User::factory()->create(); $post = Post::factory()->for($user)->create(); $response = $this ->actingAs($user) ->delete("/posts/{$post->id}"); $response->assertRedirect('/posts'); $this->assertModelMissing($post);});test('Beitrag eines anderen Nutzers ist nicht löschbar', function () { $user = User::factory()->create(); $otherUser = User::factory()->create(); $post = Post::factory()->for($otherUser)->create(); $this ->actingAs($user) ->delete("/posts/{$post->id}") ->assertForbidden(); $this->assertModelExists($post);});
Traits wie RefreshDatabase oder DatabaseTransactions lassen sich bequem über uses() einbinden. Am Dateianfang angewendet, gilt es für die gesamte Datei.
Einmal in tests/Pest.php konfiguriert, wird RefreshDatabase automatisch in allen Feature-Tests aktiviert. Einzelne Testdateien können das überschreiben.
Pest und PHPUnit lassen sich im selben Projekt einsetzen. Bestehende PHPUnit-Tests müssen nicht umgeschrieben werden; Sie schreiben lediglich neue Tests im Pest-Format.
./vendor/bin/pest # alle Tests mit Pest ausführen (auch PHPUnit-Tests)./vendor/bin/pest --filter="Nutzer" # nach Testnamen filternphp artisan test # auch über das Artisan-Kommando läuft Pest
Ab Laravel 11 verwendet php artisan test automatisch Pest, sofern Pest installiert ist.
In tests/Pest.php die uses()-Konfiguration ergänzen
Neue Tests im Pest-Format schreiben
Bestehende PHPUnit-Tests behutsam und mit Prüfung migrieren
Es ist nicht nötig, alle Tests hastig umzuschreiben. Da die Syntax von Pest gegenüber PHPUnit weniger Lernaufwand erfordert, verbreitet sie sich im Team meist reibungslos.
Pest ersetzt PHPUnit nicht, sondern ist eine darauf aufsetzende Schicht. Die Laravel-Integration ist tief; im Starterkit-Setup wird Pest als Default gewählt. Die Einführung in Bestandsprojekte ist günstig – schon der Einstieg mit neuen Tests bringt Nutzen.Wenn mehr Tests geschrieben werden, werden Bugs früher entdeckt und die Hürde vor Refactorings sinkt. Pest ist ein Werkzeug, um genau diese „Reibung beim Testschreiben” zu reduzieren.
Offizielle Pest-Dokumentation
Zu Datasets, Coverage, paralleler Ausführung und allen weiteren Funktionen von Pest konsultieren Sie die offizielle Dokumentation.