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

7.3 KiB

inclusion
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

@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

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

@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

@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

@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

mvn test

Coverage Report generieren

mvn jacoco:report

Coverage Report prüfen

# 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