Files
Orchestrator/bahn/aisupport/prompts/unit-tests-motivation.md
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

257 lines
7.3 KiB
Markdown

---
inclusion: manual
---
# Unit Tests schreiben
> **Nutzung:** Referenziere diese Datei mit `#unit-tests-motivation` im Chat und sage:
> "Schreibe Unit Tests für [Komponente/Klasse/Funktion] nach diesem Leitfaden."
---
## Ziel
Effektive Anleitung für LLMs zur Erstellung qualitativ hochwertiger Unit Tests mit klaren Erwartungen und Best Practices.
## Motivation & Kontext
Erhöhe die Unit-Test-Abdeckung im Projekt.
- Ziel: Schreibe Unit-Tests (JUnit 5) für das Projekt, sodass die gesamte Code Coverage auf mindestens 80% steigt.
- Einschränkungen (nicht ändern):
- Verändere keinen Produktionscode unter `src/main/java`.
- Verändere keine vorhandenen Tests unter `src/test/java`.
- Verändere keine bestehenden Quell-Dateinamen oder APIs.
- Keine Netzwerke/DBs in Unit-Tests; externe Abhängigkeiten nur mocken.
- Erlaubt:
- Neue Testklassen und Test-Hilfsklassen unter `src/test/java` anlegen.
- Test-spezifische Ressourcen unter `src/test/resources`.
- Anforderungen an Tests:
- Nutze JUnit 5 (`@Test`), Moq/Mockito für Abhängigkeiten.
- Tests sollen deterministisch, schnell und isoliert sein.
- Jede getestete Klasse sollte sinnvolle Positive-/Negative-/Randfall-Tests bekommen.
- Benenne Tests nach der vorhandenen Nomenklatur.
- Verifizierung (Automatisierte Checks):
1. Build: Projekt baut erfolgreich (Exit-Code 0). Kommando: `mvn test`.
2. Tests: Alle Tests laufen grün (keine Failures/Errors).
3. Coverage: Generiere Coverage-Report (mvn jacoco:report). Akzeptanz: Gesamte Projekt-Coverage >= 80% (Line Coverage). Report-Pfad: `target/site/jacoco/index.html`.
- Zusätzliche Hinweise:
- Keine Refactorings am Produktionscode.
- Falls ein Test-only Helper oder Fixture nötig ist, lege diese ausschließlich unter `src/test/java` an.
## Constraints
**Du MUST:**
- Tests für alle öffentlichen Methoden/Funktionen schreiben
- Sowohl positive als auch negative Testfälle abdecken
- Aussagekräftige Testnamen verwenden, die das erwartete Verhalten beschreiben
- Arrange-Act-Assert (AAA) Pattern befolgen
- Tests isoliert und unabhängig voneinander halten
- Mocks/Stubs für externe Abhängigkeiten verwenden
**Du SHOULD:**
- Edge Cases und Grenzwerte testen
- Fehlerbehandlung und Exception-Szenarien abdecken
- Parametrisierte Tests für ähnliche Testfälle nutzen
- Test-Fixtures und Setup-Methoden sinnvoll einsetzen
**Du MUST NOT:**
- Tests schreiben, die von externen Ressourcen abhängen (Datenbank, Netzwerk, Dateisystem)
- Tests erstellen, die eine bestimmte Ausführungsreihenfolge erfordern
- Implementation Details testen statt Verhalten
- Produktionscode unter `src/main/java` verändern
- Bestehende Tests unter `src/test/java` modifizieren
## Test-Struktur
### Namenskonvention
```
[MethodName]_[Scenario]_[ExpectedBehavior]
```
Beispiele:
- `calculateTotal_WithValidItems_ReturnsCorrectSum`
- `processPayment_WithInsufficientFunds_ThrowsException`
- `getUserById_WhenUserNotFound_ReturnsNull`
### AAA Pattern
```java
@Test
void testMethodName_Scenario_ExpectedBehavior() {
// Arrange - Setup test data and dependencies
[Test-Setup]
// Act - Execute the method under test
[Methodenaufruf]
// Assert - Verify the expected outcome
[Assertions]
}
```
## Testabdeckung
### Prioritäten
1. **Kritische Geschäftslogik** - Kernfunktionalität mit hohem Risiko
2. **Komplexe Algorithmen** - Berechnungen, Transformationen, Validierungen
3. **Fehlerbehandlung** - Exception-Handling, Validierung
4. **Edge Cases** - Grenzwerte, null/empty, unerwartete Eingaben
5. **Integration Points** - Schnittstellen zu anderen Komponenten
### Mindestabdeckung
- **Gesamtprojekt:** 80%+ Line Coverage (Ziel)
- **Kritische Komponenten:** 90%+ Code Coverage
- **Standard-Komponenten:** 80%+ Code Coverage
## Technologie-spezifische Guidelines
### JUnit 5 + Mockito
```java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
class ServiceTest {
@Mock
private Dependency mockDependency;
private Service service;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
service = new Service(mockDependency);
}
@Test
void methodName_Scenario_ExpectedBehavior() {
// Arrange
when(mockDependency.someMethod()).thenReturn(expectedValue);
// Act
Result result = service.methodUnderTest();
// Assert
assertNotNull(result);
assertEquals(expectedValue, result.getValue());
verify(mockDependency).someMethod();
}
}
```
## Beispiele
### Beispiel 1: Einfacher Unit Test
```java
@Test
void add_TwoPositiveNumbers_ReturnsSum() {
// Arrange
Calculator calculator = new Calculator();
// Act
int result = calculator.add(5, 3);
// Assert
assertEquals(8, result);
}
```
### Beispiel 2: Test mit Mocks
```java
@Test
void processOrder_ValidOrder_CallsPaymentService() {
// Arrange
Order order = new Order(100.0);
when(mockPaymentService.charge(100.0)).thenReturn(true);
// Act
boolean result = orderProcessor.process(order);
// Assert
assertTrue(result);
verify(mockPaymentService).charge(100.0);
}
```
### Beispiel 3: Exception Test
```java
@Test
void divide_ByZero_ThrowsArithmeticException() {
// Arrange
Calculator calculator = new Calculator();
// Act & Assert
assertThrows(ArithmeticException.class, () -> {
calculator.divide(10, 0);
});
}
```
## Häufige Fehler vermeiden
| Fehler | Lösung |
|--------|--------|
| Tests testen Implementation statt Verhalten | Fokus auf öffentliche API und erwartete Ergebnisse |
| Zu viele Assertions pro Test | Ein Test = Ein Konzept/Verhalten |
| Fragile Tests durch harte Abhängigkeiten | Dependency Injection und Mocking nutzen |
| Unklare Fehlermeldungen | Aussagekräftige Assert-Messages verwenden |
| Tests ohne Arrange-Phase | Immer explizites Setup, auch wenn minimal |
| Produktionscode ändern | Nur Tests unter `src/test/java` anlegen |
## Checkliste
Vor dem Abschluss prüfen:
- [ ] Alle öffentlichen Methoden haben Tests
- [ ] Positive und negative Szenarien abgedeckt
- [ ] Edge Cases berücksichtigt
- [ ] Testnamen sind selbsterklärend
- [ ] Tests sind unabhängig und isoliert
- [ ] Keine externen Abhängigkeiten
- [ ] AAA-Pattern konsequent angewendet
- [ ] Code Coverage Ziel (80%) erreicht
- [ ] `mvn test` läuft erfolgreich durch
- [ ] Kein Produktionscode verändert
## Verifizierung
### Build & Test ausführen
```bash
mvn test
```
### Coverage Report generieren
```bash
mvn jacoco:report
```
### Coverage Report prüfen
```bash
# Report-Pfad: target/site/jacoco/index.html
# Ziel: >= 80% Line Coverage
```
## Troubleshooting
### Tests schlagen fehl
- Prüfe ob Mocks korrekt konfiguriert sind
- Verifiziere Test-Daten und erwartete Werte
- Stelle sicher, dass Tests isoliert laufen
### Niedrige Code Coverage
- Identifiziere ungetestete Branches mit Jacoco-Report
- Füge Tests für Exception-Handling hinzu
- Teste Edge Cases und Grenzwerte
- Prüfe ob alle öffentlichen Methoden getestet sind
### Langsame Tests
- Ersetze echte Abhängigkeiten durch Mocks
- Vermeide Thread.sleep() und Timeouts
- Nutze In-Memory Implementierungen