- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
4.4 KiB
4.4 KiB
Testing-Richtlinien
Übersicht
Diese Richtlinien beschreiben die Standards und Best Practices für Tests im Framework.
Grundprinzipien
1. Testarten
- Unit Tests: Testen einzelner Komponenten isoliert
- Integrationstests: Testen des Zusammenspiels mehrerer Komponenten
- Funktionstests: Testen ganzer Funktionalitäten aus Benutzersicht
2. Pest-Framework
Alle Tests werden mit dem Pest-Framework geschrieben:
test('Analytics::track zeichnet Events korrekt auf', function () {
// Arrange
$manager = new AnalyticsManager(['enabled' => true], new InMemoryStorage());
$analytics = new Analytics($manager, new EventDispatcher());
// Act
$analytics->track('test_event', ['key' => 'value']);
// Assert
expect($manager->getStorage()->retrieve())->toHaveCount(1);
expect($manager->getStorage()->retrieve()[0]['event'])->toBe('test_event');
});
3. Teststruktur
- Jeder Test folgt dem AAA-Prinzip: Arrange, Act, Assert
- Tests sollten unabhängig voneinander sein
- Tests sollten deterministisch sein (keine zufälligen Ergebnisse)
Best Practices
1. Testabdeckung
- Jede öffentliche Methode sollte getestet werden
- Edge Cases und Fehlersituationen explizit testen
- Fokus auf Business-Logik und kritische Pfade
2. Mocking
- Externe Abhängigkeiten mocken
- Eigene Test-Implementierungen für Interfaces erstellen
- Mock-Objekte nur für die spezifischen Testfälle konfigurieren
// Beispiel: Test mit Mock
test('Fehlerbehandlung bei Storage-Ausfall', function () {
// Arrange
$storage = new class implements StorageInterface {
public function store(array $events): void
{
throw new \RuntimeException('Storage-Fehler');
}
public function retrieve(array $filters = []): array
{
return [];
}
public function clear(): void
{
}
};
$manager = new AnalyticsManager(['enabled' => true], $storage);
// Act & Assert
expect(fn() => $manager->flush())->toThrow(\RuntimeException::class);
});
3. Fixtures und Factories
- Testdaten mit Factories erstellen
- Komplexe Objekte über Helpers aufbauen
- Wiederverwendbare Fixtures für ähnliche Tests
// Beispiel: Test-Factory
function createAnalyticsManager(array $config = []): AnalyticsManager
{
$defaultConfig = ['enabled' => true, 'auto_flush' => false];
return new AnalyticsManager(
array_merge($defaultConfig, $config),
new InMemoryStorage()
);
}
test('Auto-Flush funktioniert korrekt', function () {
// Arrange
$manager = createAnalyticsManager(['auto_flush' => true, 'batch_size' => 2]);
// Act
$manager->track('event1', []);
$manager->track('event2', []);
// Assert
expect($manager->getStorage()->retrieve())->toHaveCount(2);
});
4. Datenbankzugriffe
- In Unit-Tests Datenbankzugriffe vermeiden oder mocken
- In Integrationstests separate Testdatenbank verwenden
- Testdatenbank nach Tests zurücksetzen
5. Asynchrone Tests
- Timeouts für asynchrone Tests setzen
- Auf Async-Events warten, statt feste Wartezeiten
Testorganisation
1. Dateistruktur
- Tests in
/tests-Verzeichnis mit gleicher Struktur wie/src - Dateinamen mit
Test-Suffix
2. Testgruppen
- Tests mit Attributen in Gruppen einteilen
- Langsame Tests markieren
#[Group('analytics')]
#[Group('slow')]
test('große Datenmenge verarbeiten', function () {
// Test mit vielen Daten
});
CI/CD-Integration
- Tests in CI-Pipeline automatisiert ausführen
- Testabdeckung messen und überwachen
- Pull Requests nur mit erfolgreichen Tests mergen
Fehlersuche
1. Debugging-Techniken
- Pest-Debugging aktivieren mit
->dump() - PHPUnit-Assertions für detaillierte Fehlermeldungen
test('komplexes Objekt validieren', function () {
$result = processData();
// Bei Fehlern Kontext ausgeben
if (!expect($result->isValid())->toBeTrue()->isSuccess()) {
dump($result->getErrors());
}
});
2. Problematische Tests
- Flaky Tests identifizieren und beheben
- Tests isolieren mit
onlyoderskip
test('problematischer Test', function () {
// Test-Code
})->skip('Wird untersucht');
Zusammenfassung
- Tests sind ein integraler Bestandteil der Codebase
- Qualität und Wartbarkeit der Tests sind genauso wichtig wie die des Produktionscodes
- Tests dienen als lebende Dokumentation der Funktionalität