Files
Orchestrator/bahn/O2C-Harness/testing.md
T
ankn a5f8fb49ab Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
      Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
      Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)

Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
2026-06-30 20:39:52 +02:00

228 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Testing Standards
## Coverage
- **Minimum: 80% Line Coverage** kein Merge unter 80%
- Neue Features: 90%+ Coverage anstreben
- Kritische Pfade (Auth, Payment, Data): 95%+
## Testarten
| Art | Scope | Framework |
|-----|-------|-----------|
| Unit | Einzelne Klasse/Funktion | JUnit/pytest/go test/Vitest |
| Integration | Mehrere Komponenten | @SpringBootTest/TestClient |
| E2E | Ganzer Flow | Playwright/RestAssured |
## Teststruktur: Gherkin/Given-When-Then
Alle Testfälle in Given-When-Then Struktur schreiben:
```java
@Test
void shouldReturnUserWhenValidIdProvided() {
// Given
var userId = UUID.randomUUID();
var expectedUser = new User(userId, "Max Mustermann");
when(userRepository.findById(userId)).thenReturn(Optional.of(expectedUser));
// When
var result = userService.findById(userId);
// Then
assertThat(result).isPresent();
assertThat(result.get().getName()).isEqualTo("Max Mustermann");
}
```
```python
def test_should_return_user_when_valid_id():
# Given
user_id = uuid4()
mock_repo.find_by_id.return_value = User(id=user_id, name="Max")
# When
result = user_service.find_by_id(user_id)
# Then
assert result is not None
assert result.name == "Max"
```
## Was testen
- Happy Path (Normalfall)
- Edge Cases (leere Listen, None/null, Grenzwerte)
- Error Cases (ungültige Eingaben, Exceptions)
- Security (unautorisierter Zugriff, SQL Injection Inputs)
## Was NICHT testen
- Getter/Setter ohne Logik
- Framework-Code (Spring Boot Auto-Config)
- Third-Party Libraries
## E2E-Tests mit Playwright (nach Deploy auf Preview)
Wenn das Projekt eine Webapp ist und auf der Preview-Umgebung deployed wurde:
### Preview-URL
```
https://{app-name}-{namespace}.${ART_NAME}-iat.cnp-test.comp.db.de
```
### E2E-Tests durchführen
Nutze den Playwright MCP Server (ist im Pod verfügbar):
1. Zur Preview-URL navigieren
2. Seite laden, prüfen ob Grundfunktionen da sind
3. Formulare ausfüllen, Buttons klicken
4. Responses/Ergebnisse prüfen
5. Screenshots als Evidenz
### Beispiel-Prüfungen
- Startseite lädt ohne Fehler
- CRUD-Operationen funktionieren (Erstellen, Lesen, Bearbeiten, Löschen)
- Validierung greift (leere Felder, ungültige Eingaben)
- API-Endpoints antworten korrekt (JSON-Response prüfen)
### Screenshots im MR
Relevante Screenshots als Kommentar am MR anhängen oder in der MR-Description referenzieren.
### Akzeptanzkriterien in Gherkin
Testfälle als Gherkin-Szenarien. Wenn in der Aufgabe bereits Gherkin-Szenarien formuliert sind → direkt übernehmen. Sonst selbst aus der Anforderung ableiten.
```gherkin
Feature: Adressverwaltung
Scenario: Neue Adresse anlegen
Given ich bin auf der Startseite
When ich auf "Neue Adresse" klicke
And ich das Formular ausfülle:
| Feld | Wert |
| Name | Max Mustermann |
| Straße | Musterstr. 1 |
| Stadt | Berlin |
| PLZ | 10115 |
| Land | Deutschland |
And ich auf "Speichern" klicke
Then sehe ich "Max Mustermann" in der Adressliste
Scenario: Validierung bei leerem Namen
Given ich bin auf der Startseite
When ich auf "Neue Adresse" klicke
And ich das Formular ohne Name absende
Then sehe ich eine Fehlermeldung
Scenario: Adresse löschen
Given es existiert eine Adresse "Max Mustermann"
When ich auf "Löschen" klicke
Then ist "Max Mustermann" nicht mehr in der Liste
```
### Ablauf
1. Gherkin-Szenarien aus der Aufgabe ableiten
2. In GitLab Issue als Akzeptanzkriterien dokumentieren
3. Nach Deploy: Szenarien mit Playwright gegen Preview-URL ausführen
4. Jedes Szenario = ein Playwright-Test (navigieren, klicken, prüfen)
5. Bei Fehler: Screenshot + Beschreibung als MR-Kommentar
## Load-Testing mit hey
Nach erfolgreichem E2E-Test: Einfachen Last-Test gegen die Preview-URL fahren.
### Wann Load-Testing
- Bei REST APIs mit erwarteter Last
- Bei Endpoints die Datenbank-Zugriffe machen
- Nicht bei reinen Doku-Projekten oder Libraries
### Verwendung
```bash
# Einfacher GET-Test: 200 Requests, 10 parallel
hey -n 200 -c 10 http://preview-url/api/addresses
# POST mit Body und Auth
hey -n 100 -c 5 \
-m POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"name":"Load Test","street":"Teststr. 1","city":"Berlin","zip":"10115","country":"DE"}' \
http://preview-url/api/addresses
# PUT (Update)
hey -n 100 -c 5 \
-m PUT \
-H "Content-Type: application/json" \
-d '{"name":"Updated"}' \
http://preview-url/api/addresses/1
```
### Auswertung
hey gibt aus:
- Response-Zeiten (avg, p50, p95, p99)
- Throughput (Requests/sec)
- Status-Code-Verteilung
- Fehlerrate
### Akzeptanzkriterien (Richtwerte)
- p95 Response-Zeit < 500ms
- Fehlerrate < 1%
- Keine 5xx Errors unter Last
### Ergebnis dokumentieren
Load-Test-Ergebnisse als Kommentar am MR oder in Session-Notes festhalten.
Wenn Ergebnisse schlecht: Performance-Issue anlegen.
## Integration Tests mit Testcontainers
Für Integration Tests mit echten Datenbanken/Services: [testcontainers.org](https://testcontainers.org)
### Verwendung
```java
@SpringBootTest
@Testcontainers
class UserRepositoryIT {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@Test
void shouldSaveAndFindUser() {
// Given-When-Then
}
}
```
### Im Agent-Pod
- Podman ist im Base-Image installiert (Testcontainers-kompatibel)
- Env-Variablen für Testcontainers mit Podman sind gesetzt:
- `TESTCONTAINERS_RYUK_DISABLED=true`
- `DOCKER_HOST=unix:///run/podman/podman.sock`
### Wann Testcontainers nutzen
- Repository-Tests mit echter DB (statt H2)
- Kafka-Integration Tests
- Tests gegen externe Services (Wiremock-Container)
- NICHT für Unit-Tests (dort Mocks verwenden)