Laravel Pest Test Generator
Grundprinzipien
- Pest-Syntax (nicht PHPUnit). 2. Arrange-Act-Assert. 3. Ein Assert pro Test.
- Factories nutzen. 5. RefreshDatabase. 6. Sprechende Namen.
Workflow
- Scan: Existierende Tests, Models, Controller, Services, Routes, Jobs identifizieren
- Plan: Test-Prioritäten festlegen (KRITISCH → NÜTZLICH)
- Infrastruktur: Pest.php, Factories, Test-Helpers prüfen
- Schreiben: Tests nach Patterns unten
- Ausführen:
php artisan test oder vendor/bin/pest
Test-Prioritäten
| Priorität |
Was testen |
| KRITISCH |
Auth, Login, Passwort, Rollen, Payment |
| HOCH |
CRUD-Operationen, Business-Logik, API-Endpoints |
| MITTEL |
Validierung, Edge Cases, Mail, Jobs |
| NÜTZLICH |
UI-Komponenten, Filament-Pages, Helfer |
Test-Patterns
A) Route/Controller (Feature)
it('returns 200 for published items', function () {
$item = Item::factory()->published()->create();
$this->get("/items/{$item->slug}")->assertOk();
});
it('returns 404 for unpublished items', function () {
$item = Item::factory()->unpublished()->create();
$this->get("/items/{$item->slug}")->assertNotFound();
});
it('requires auth for admin routes', function () {
$this->get('/admin')->assertRedirect('/login');
});
B) Service/Business Logic (Unit)
it('calculates tax correctly', function () {
$service = new TaxService();
expect($service->calculate(100, 'AT'))->toBe(120.0);
});
C) Model
it('has correct fillable fields', function () {
$model = new Item();
expect($model->getFillable())->toContain('title', 'slug');
});
it('scopes to published only', function () {
Item::factory()->published()->count(2)->create();
Item::factory()->unpublished()->create();
expect(Item::published()->count())->toBe(2);
});
D) Job/Queue
it('dispatches notification job', function () {
Queue::fake();
$order->markAsPaid();
Queue::assertPushed(SendInvoiceJob::class);
});
it('handles job chain correctly', function () {
Queue::fake();
ProcessPayment::withChain([SendInvoice::class])->dispatch($order);
Queue::assertPushed(ProcessPayment::class);
});
E) Livewire
it('can search items', function () {
$item = Item::factory()->create(['title' => 'Unique']);
Livewire::test(ItemList::class)
->set('search', 'Unique')
->assertSee('Unique');
});
F) Security
it('prevents unauthorized access', function () {
$user = User::factory()->create();
$this->actingAs($user)->get('/admin/users')->assertForbidden();
});
it('validates CSRF on forms', function () {
$this->post('/contact', ['name' => 'Test'])->assertStatus(419);
});
it('rate limits login attempts', function () {
for ($i = 0; $i < 6; $i++) {
$this->post('/login', ['email' => 'a@b.com', 'password' => 'wrong']);
}
$this->post('/login', ['email' => 'a@b.com', 'password' => 'wrong'])
->assertStatus(429);
});
G) Filament Admin
it('admin can access dashboard', function () {
$admin = User::factory()->admin()->create();
$this->actingAs($admin)->get('/admin')->assertOk();
});
Hinweise
- RefreshDatabase für Feature Tests, DatabaseTransactions wenn schneller nötig
- Mail::fake(), Queue::fake(), Notification::fake() für Side-Effects
- Externe APIs (Mollie, VIES) immer mocken
- Factories mit States:
->published(), ->admin(), ->withTeam()
- Ziel: min. 80% Coverage auf Auth, Payment, Business Logic
1---2name: laravel-tests3description: Generiert Pest-Tests für Laravel. Scannt Codebase, erstellt Tests nach Priorität. Nutze bei: "Tests schreiben", "Test generieren", "Pest Tests", "Feature Tests", "Unit Tests", "teste den Controller/Model/Service", "Coverage verbessern", "ist das getestet?", "Refactoring absichern".4---56# Laravel Pest Test Generator78## Grundprinzipien9101. Pest-Syntax (nicht PHPUnit). 2. Arrange-Act-Assert. 3. Ein Assert pro Test.114. Factories nutzen. 5. RefreshDatabase. 6. Sprechende Namen.1213## Workflow14151. **Scan:** Existierende Tests, Models, Controller, Services, Routes, Jobs identifizieren162. **Plan:** Test-Prioritäten festlegen (KRITISCH → NÜTZLICH)173. **Infrastruktur:** Pest.php, Factories, Test-Helpers prüfen184. **Schreiben:** Tests nach Patterns unten195. **Ausführen:** `php artisan test` oder `vendor/bin/pest`2021## Test-Prioritäten2223| Priorität | Was testen |24|---|---|25| KRITISCH | Auth, Login, Passwort, Rollen, Payment |26| HOCH | CRUD-Operationen, Business-Logik, API-Endpoints |27| MITTEL | Validierung, Edge Cases, Mail, Jobs |28| NÜTZLICH | UI-Komponenten, Filament-Pages, Helfer |2930## Test-Patterns3132### A) Route/Controller (Feature)3334```php35it('returns 200 for published items', function () {36 $item = Item::factory()->published()->create();37 $this->get("/items/{$item->slug}")->assertOk();38});3940it('returns 404 for unpublished items', function () {41 $item = Item::factory()->unpublished()->create();42 $this->get("/items/{$item->slug}")->assertNotFound();43});4445it('requires auth for admin routes', function () {46 $this->get('/admin')->assertRedirect('/login');47});48```4950### B) Service/Business Logic (Unit)5152```php53it('calculates tax correctly', function () {54 $service = new TaxService();55 expect($service->calculate(100, 'AT'))->toBe(120.0);56});57```5859### C) Model6061```php62it('has correct fillable fields', function () {63 $model = new Item();64 expect($model->getFillable())->toContain('title', 'slug');65});6667it('scopes to published only', function () {68 Item::factory()->published()->count(2)->create();69 Item::factory()->unpublished()->create();70 expect(Item::published()->count())->toBe(2);71});72```7374### D) Job/Queue7576```php77it('dispatches notification job', function () {78 Queue::fake();79 $order->markAsPaid();80 Queue::assertPushed(SendInvoiceJob::class);81});8283it('handles job chain correctly', function () {84 Queue::fake();85 ProcessPayment::withChain([SendInvoice::class])->dispatch($order);86 Queue::assertPushed(ProcessPayment::class);87});88```8990### E) Livewire9192```php93it('can search items', function () {94 $item = Item::factory()->create(['title' => 'Unique']);95 Livewire::test(ItemList::class)96 ->set('search', 'Unique')97 ->assertSee('Unique');98});99```100101### F) Security102103```php104it('prevents unauthorized access', function () {105 $user = User::factory()->create();106 $this->actingAs($user)->get('/admin/users')->assertForbidden();107});108109it('validates CSRF on forms', function () {110 $this->post('/contact', ['name' => 'Test'])->assertStatus(419);111});112113it('rate limits login attempts', function () {114 for ($i = 0; $i < 6; $i++) {115 $this->post('/login', ['email' => 'a@b.com', 'password' => 'wrong']);116 }117 $this->post('/login', ['email' => 'a@b.com', 'password' => 'wrong'])118 ->assertStatus(429);119});120```121122### G) Filament Admin123124```php125it('admin can access dashboard', function () {126 $admin = User::factory()->admin()->create();127 $this->actingAs($admin)->get('/admin')->assertOk();128});129```130131## Hinweise132133- **RefreshDatabase** für Feature Tests, **DatabaseTransactions** wenn schneller nötig134- **Mail::fake()**, **Queue::fake()**, **Notification::fake()** für Side-Effects135- Externe APIs (Mollie, VIES) immer mocken136- Factories mit States: `->published()`, `->admin()`, `->withTeam()`137- Ziel: min. 80% Coverage auf Auth, Payment, Business Logic