Files
Orchestrator/bahn/O2C-Harness/testing.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

6.1 KiB
Raw Permalink Blame History

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:

@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");
}
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.

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

# 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

Verwendung

@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)