docs: update testing strategy and define directory symmetry
This commit is contained in:
+40
-2
@@ -634,8 +634,46 @@ readonly class ShippingProvider implements ShippingProviderInterface
|
|||||||
return $this->mapper->toModel($response);
|
return $this->mapper->toModel($response);
|
||||||
} catch (TransportException $e) {
|
} catch (TransportException $e) {
|
||||||
throw new ExternalSystemUnavailableException('Shipping API is down', 0, $e);
|
throw new ExternalSystemUnavailableException('Shipping API is down', 0, $e);
|
||||||
}
|
|
||||||
}
|
## 13. Testing Strategy & Structure
|
||||||
|
Die Testsuite ist so aufgebaut, dass sie die Schichtenmodell-Architektur widerspiegelt. Dies erleichtert die Wartung und stellt sicher, dass jede Komponente auf der richtigen Abstraktionsebene geprüft wird.
|
||||||
|
|
||||||
|
### Verzeichnisstruktur & Mapping
|
||||||
|
Die Struktur unter `tests/` folgt strikt der Symmetrie zu `src/`:
|
||||||
|
|
||||||
|
| Test Typ | Pfad in `tests/` | Spiegelt $\rightarrow$ | Werkzeug / Ansatz | Fokus |
|
||||||
|
| :--- | :--- | :--- | :--- | :--- |
|
||||||
|
| **Unit** | `tests/Unit/Logic/` | `src/Logic/` | PHPUnit + Mocks | Pure Business Logic & Edge Cases. |
|
||||||
|
| **Integration** | `tests/Integration/Data/` | `src/Data/` | Real DB (Test-Env) | Repositories, Mapper, Infrastruktur. |
|
||||||
|
| **Functional UI**| `tests/Functional/UI/` | `src/UI/` | Symfony `WebTestCase` | Einzelspezifische Endpunkte / Requests. |
|
||||||
|
| **Functional E2E**| `tests/Functional/Scenarios/`| (Szenario-basiert) | Symfony `WebTestCase` | Komplexe User Flows (Multi-Step). |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Detaillierte Guidelines
|
||||||
|
|
||||||
|
#### 1. Unit Tests (`tests/Unit/Logic`)
|
||||||
|
Da die Logic Layer "Pure PHP" ist, müssen diese Tests extrem schnell sein.
|
||||||
|
- **Kein Framework**: Es wird kein Symfony Kernel gebootet.
|
||||||
|
- **Mocking**: Interfaces der Data Layer (`Provider`, `Processor`, `TransactionManager`) werden gemockt.
|
||||||
|
- **Business Models**: Werden *nicht* gemockt, sondern echt verwendet (da sie zustandslos/POPOs sind).
|
||||||
|
|
||||||
|
#### 2. Integration Tests (`tests/Integration/Data`)
|
||||||
|
Hier wird die Brücke zur Infrastruktur geprüft.
|
||||||
|
- **Datenbank**: Nutzung einer dedizierten Test-DB. Jeder Test sollte in einer Transaktion laufen, die am Ende gerolled wird (oder via Database-Reset).
|
||||||
|
- **Mapper-Tests**: Explizite Prüfung: `Entity` $\rightarrow$ `toModel()` $\rightarrow$ `Business Model`.
|
||||||
|
|
||||||
|
#### 3. Functional Tests (`tests/Functional`)
|
||||||
|
Diese nutzen den Symfony `WebTestCase`, um das System als "Black Box" zu testen.
|
||||||
|
- **UI Mirroring**: In `tests/Functional/UI` wird pro Controller ein entsprechender Test-Case angelegt, der die HTTP-Antworten (Status-Codes, JSON-Struktur) validiert.
|
||||||
|
- **Scenario-Tests**: In `tests/Functional/Scenarios` werden reale Business Flows abgebildet (z.B. `OrderProcessTest`), die mehrere API-Calls hintereinander ausführen und den finalen Zustand in der Datenbank prüfen.
|
||||||
|
|
||||||
|
#### 4. Mocking Guidelines
|
||||||
|
Um "fragile Tests" zu vermeiden, gilt:
|
||||||
|
- **Mock a Interface, not a Class**: Mocke immer das Interface (z.B. `OrderProviderInterface`), niemals die konkrete Implementierung (`OrderProvider`).
|
||||||
|
- **No Mocks for Models/DTOs**: Value Objects und Business Models werden immer echt instanziiert.
|
||||||
|
- **Avoid Mocking 3rd Party Libs**: Wenn externe Libs getestet werden müssen, schreibe einen eigenen Wrapper/Interface in die Logic Layer und mocke diesen.
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+9
-8
@@ -72,21 +72,22 @@ Zur Entkopplung zeitintensiver Prozesse wird ein Message-Bus eingesetzt. Dabei g
|
|||||||
- **Ort**: Message-Handler befinden sich in der **UI Layer**.
|
- **Ort**: Message-Handler befinden sich in der **UI Layer**.
|
||||||
- **Rolle**: Da ein asynchroner Nachrichteneingang ein externer Eintrittspunkt ist, fungiert der Handler als Adapter. Er nimmt die Message entgegen und delegiert die eigentliche Verarbeitung an einen entsprechenden UseCase oder Workflow in der Logic Layer.
|
- **Rolle**: Da ein asynchroner Nachrichteneingang ein externer Eintrittspunkt ist, fungiert der Handler als Adapter. Er nimmt die Message entgegen und delegiert die eigentliche Verarbeitung an einen entsprechenden UseCase oder Workflow in der Logic Layer.
|
||||||
|
|
||||||
## 6. Teststrategie
|
## 6. Teststrategie & Symmetrie
|
||||||
|
Um eine hohe Codequalität und Wartbarkeit zu gewährleisten, wird eine pyramidale Teststrategie verfolgt. Dabei gilt das Prinzip der **Symmetrie**: Die Verzeichnisstruktur unter `tests/` spiegelt exakt die Struktur von `src/` wider, um die Auffindbarkeit von Tests sicherzustellen.
|
||||||
Um eine hohe Codequalität und Wartbarkeit zu gewährleisten, wird eine pyramidale Teststrategie verfolgt:
|
|
||||||
|
|
||||||
### Unit Tests (Logic Layer)
|
### Unit Tests (Logic Layer)
|
||||||
- **Fokus**: Reine Geschäftslogik, Models, UseCases.
|
- **Fokus**: Reine Geschäftslogik, Models, UseCases.
|
||||||
- **Regel**: Diese Tests dürfen *keine* echte Datenbank oder externe APIs nutzen. Abhängigkeiten zur Data Layer werden zwingend durch Mocks/Doubles der Interfaces ersetzt.
|
- **Regel**: Diese Tests dürfen *keine* echte Datenbank oder externe APIs nutzen. Abhängigkeiten zur Data Layer werden zwingend durch Mocks/Doubles der Interfaces ersetzt.
|
||||||
- **Ziel**: Schnelle Ausführung und vollständige Abdeckung der Edge-Cases in der Business-Logik.
|
- **Ziel**: Schnelle Ausführung und vollständige Abdeckung der Edge-Cases in der Business-Logik.
|
||||||
|
|
||||||
### Integration Tests (Data & UI Layer)
|
### Integration Tests (Data Layer)
|
||||||
- **Fokus**: Korrekte Persistenz (Repositories, Processor) und korrekte Endpunkt-Konfiguration (Controller, Handler).
|
- **Fokus**: Korrekte Persistenz (Repositories, Processor) und Mapping.
|
||||||
- **Regel**: Nutzen eine echte Test-Datenbank oder einen In-Memory-Speicher. Hier wird geprüft, ob die Kommunikation zwischen den Schichten und zum Framework funktioniert.
|
- **Regel**: Nutzen eine echte Test-Datenbank oder einen In-Memory-Speicher. Hier wird geprüft, ob die technische Implementierung der Data-Layer korrekt funktioniert.
|
||||||
|
|
||||||
### Functional / E2E Tests
|
### Functional Tests (UI Layer & Scenarios)
|
||||||
- **Fokus**: Durchlauf kompletter Business-Szenarien von der UI bis zur Data Layer.
|
- **Fokus**: Durchlauf kompletter Business-Szenarien und Validierung von API-Endpunkten.
|
||||||
|
- **Werkzeug**: Einsatz des Symfony `WebTestCase`.
|
||||||
|
- **Ziel**: Sicherstellung, dass die Kette UI $\rightarrow$ Logic $\rightarrow$ Data konsistent funktioniert.
|
||||||
|
|
||||||
## 7. Logging & Observability
|
## 7. Logging & Observability
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user