Skip to content
Produkt

Fallstudie: Automatische Testgenerierung mit dem Coding Agent

Ein praktischer Durchgang zum Aufbau eines Workflows, der den Coding Agent nutzt, um automatisch Unit-Tests für nicht getestete Module zu generieren und 95%+ Abdeckung zu erreichen.

JT
JieGou Team
· · 9 Min. Lesezeit

Testabdeckung ist eine dieser Metriken, bei der jeder zustimmt, dass sie wichtig ist, und niemand dafür verantwortlich sein will, sie zu verbessern. Sie kennen das Muster: Eine Codebase beginnt bei 90% Abdeckung, dann werden ein paar Features ohne Tests ausgeliefert, dann überspringt ein Refactoring das Test-Update, weil “wir kommen darauf zurück.” Sechs Monate später sind Sie bei 60% und der Weg zurück fühlt sich wie ein Vollzeitjob an, für den sich niemand angemeldet hat.

Diese Fallstudie zeigt, wie ein Team einen JieGou-Workflow mit dem Coding Agent genutzt hat, um in drei Wochen von 60% auf 94% Testabdeckung zu kommen — automatisch, mit minimalem menschlichem Eingriff.

Das Problem

Die betreffende Codebase war ein Node.js-Backend mit 312 Modulen. Die Abdeckung war seit Monaten stetig gesunken:

  • 60% Gesamttestabdeckung, von 85% zu Jahresbeginn gesunken
  • 47 Module ohne jegliche Tests — hauptsächlich Hilfsfunktionen, Datentransformatoren und Validierungslogik
  • Neue Features wurden ohne Tests ausgeliefert, weil Entwickler sich auf Liefertermine konzentrierten
  • CI-Pipeline führte Tests aus, aber erzwang keine Abdeckungsschwellen, sodass der Rückgang unsichtbar war, bis jemand nachschaute

Das Team hatte zweimal versucht, “Test-Schreib-Sprints” einzuplanen. Beide Male wurde der Sprint deprioritisiert, als eine Kundeneskalation kam. Manuelles Testschreiben ist langsam, mühsam und konkurriert mit jeder anderen Priorität.

Der Workflow

Das Team baute einen 4-Schritt-Workflow in JieGou, der automatisch ausgelöst wird, wenn Code in main gemergt wird. Kein manueller Eingriff erforderlich, es sei denn, ein generierter Test muss überarbeitet werden.

Schritt 1: Trigger — GitHub-Webhook bei PR-Merge

Der Workflow beginnt mit einem Webhook-Trigger, der auslöst, wenn ein Pull Request in main gemergt wird.

trigger:
  type: webhook
  source: github
  events: ["pull_request.closed"]
  filters:
    - field: "action"
      value: "closed"
    - field: "pull_request.merged"
      value: true
    - field: "pull_request.base.ref"
      value: "main"

Die Webhook-Payload enthält die Liste der geänderten Dateien, den Merge-Commit-SHA und die PR-Metadaten. All dies fließt in den nächsten Schritt.

Schritt 2: Analysieren — Nicht getestete Funktionen identifizieren

Ein Recipe-Schritt nimmt die Liste der geänderten Dateien vom Webhook und gleicht sie mit dem aktuellsten Abdeckungsbericht ab. Der Recipe-Prompt ist unkompliziert:

step: analyze-coverage
type: recipe
model: claude-sonnet-4-6
input:
  changed_files: "{{trigger.pull_request.changed_files}}"
  coverage_report: "{{secrets.COVERAGE_REPORT_URL}}"
prompt: |
  You are a test coverage analyst. Given the list of changed files
  and the coverage report (lcov format), identify:

  1. Which changed files have less than 80% line coverage
  2. Which exported functions in those files have zero coverage
  3. The function signatures and a brief description of what each does

  Output a JSON array of objects with fields:
  file_path, function_name, signature, description, current_coverage

Dieser Schritt erzeugt eine strukturierte Liste genau jener Funktionen, die Tests brauchen. Er filtert Dateien heraus, die bereits ausreichende Abdeckung haben, sodass der Coding Agent keine Zeit mit bereits getestetem Code verschwendet.

Schritt 3: Generieren — Coding Agent schreibt die Tests

Hier erledigt der Coding Agent die Hauptarbeit. Er empfängt die Liste der nicht getesteten Funktionen, klont das Repository und schreibt Unit-Tests für jede einzelne.

step: generate-tests
type: coding-agent
model: claude-sonnet-4-6
repo: "{{secrets.REPO_URL}}"
branch: "test-gen/{{trigger.pull_request.number}}"
maxTurns: 30
sandbox:
  memory: "1GB"
  timeout: "5m"
  network: false
tools:
  - read
  - write
  - edit
  - bash
  - glob
  - grep
input:
  untested_functions: "{{steps.analyze-coverage.output}}"
task: |
  You are a senior test engineer. Your job is to write unit tests for
  the following untested functions:

  {{untested_functions}}

  Instructions:
  1. Read the source file for each function to understand its behavior
  2. Read existing test files in the same directory for style conventions
  3. Write tests using the project's test framework (vitest)
  4. Each test file should cover: happy path, edge cases, error handling
  5. Run `npm test -- --reporter=verbose <test-file>` after writing each
     test file to verify all tests pass
  6. If a test fails, read the error, fix the test, and re-run
  7. Do NOT modify source code — only create or update test files

  Match the existing test style: describe blocks, clear test names,
  arrange-act-assert pattern. Use the existing fixtures and helpers
  where available.

Die wesentlichen Konfigurationsentscheidungen:

  • Modell: Claude Sonnet 4.6 — schnell genug für Hochvolumen-Testgenerierung, intelligent genug, um komplexe Funktionssignaturen und Grenzfälle zu verstehen.
  • Sandbox: 1 GB Speicher, 5-Minuten-Timeout — genügend Spielraum für npm test-Durchläufe ohne Risiko unkontrollierter Prozesse.
  • Netzwerk deaktiviert — der Agent braucht keinen externen Zugriff; alles ist im geklonten Repo.
  • maxTurns: 30 — ermöglicht dem Agenten, über mehrere Testdateien zu iterieren und Fehler über mehrere Zyklen zu beheben.

Die Aufgabenbeschreibung enthält eine kritische Anweisung: Zuerst bestehende Testdateien lesen. Dies stellt sicher, dass die generierten Tests den Konventionen des Teams entsprechen — gleicher Assertion-Stil, gleiche describe/it-Struktur, gleiche Fixture-Muster. Ohne dies sind generierte Tests technisch korrekt, aber stilistisch inkonsistent, was Reibung bei der Überprüfung schafft.

Schritt 4: Einreichen — PR mit Ergebnissen erstellen

Nachdem der Coding Agent fertig ist, erstellt ein letzter Recipe-Schritt einen Pull Request mit den generierten Tests und fügt die Testergebnisse in die PR-Beschreibung ein.

step: submit-pr
type: recipe
model: claude-sonnet-4-6
input:
  modified_files: "{{steps.generate-tests.modified_files}}"
  test_output: "{{steps.generate-tests.output}}"
  source_pr: "{{trigger.pull_request.number}}"
prompt: |
  Create a pull request with the following:
  - Title: "test: auto-generated tests for PR #{{source_pr}}"
  - Body: Include a summary of tests added, functions covered,
    and the full test output showing all tests passing
  - Label: "auto-tests"
  - Request review from the original PR author

Der PR wird mit auto-tests gelabelt, damit das Team generierte Test-PRs filtern und stapelweise überprüfen kann. Die Anforderung zur Überprüfung durch den ursprünglichen PR-Autor bedeutet, dass die Person, die den Code am besten kennt, die Tests zuerst sieht.

Ergebnisse

Das Team hat diesen Workflow drei Wochen lang bei jedem Merge in main ausgeführt. Hier sind die Zahlen:

MetrikWert
Start-Abdeckung60%
End-Abdeckung94%
Generierte Tests847
Erstellte Pull Requests42
Durchschnittliche PR-Review-Zeit12 Minuten
Tests, die bestehende Bugs fanden23
Durchschnittliche Kosten pro Tag~4,50 $ (Claude API)

Einige Dinge fallen auf.

847 Tests über 42 PRs bedeutet etwa 20 Tests pro PR. Die meisten PRs deckten 2-4 Quelldateien ab, mit 5-6 Tests pro Funktion (Happy Path, Grenzwerte, Fehlerbehandlung, null/undefined-Eingaben, Typkonvertierungs-Grenzfälle).

12 Minuten durchschnittliche Review-Zeit ist bemerkenswert. Die meisten generierten Tests waren beim ersten Durchgang korrekt. Die hauptsächlichen Review-Kommentare waren stilistisch — Umbenennung von Testbeschreibungen, Anpassung von Fixture-Daten für mehr Realismus. Sehr wenige Tests brauchten funktionale Korrekturen.

23 Tests fanden tatsächliche Bugs im bestehenden Code. Das ist das interessanteste Ergebnis. Der Coding Agent schrieb einen Test für eine Datums-Parsing-Funktion, die ISO 8601-Format erwartete, und der Test enthüllte, dass die Funktion stillschweigend Invalid Date für Zeitstempel mit Zeitzonen-Offsets zurückgab. Dieser Bug war seit vier Monaten in der Produktion. Ähnliche Entdeckungen in Validierungslogik, Off-by-One-Fehler in Paginierungshelfern und eine Race Condition in einem Caching-Modul.

4,50 $/Tag an Claude-API-Kosten sind trivial im Vergleich zur eingesparten Engineering-Zeit. Eine konservative Schätzung: 847 Tests manuell zu schreiben mit 15 Minuten pro Test würde etwa 212 Stunden dauern — über fünf Wochen Vollzeit-Engineering-Arbeit.

Gelernte Lektionen

Nach drei Wochen Betrieb dieses Workflows hat das Team seinen Ansatz basierend auf Erfahrungen verfeinert.

Mit reinen Funktionen beginnen

Die erste Version des Workflows zielte auf allen ungetesteten Code. Das funktionierte gut für reine Funktionen — Hilfsprogramme, Validatoren, Transformatoren, Formatierer — weil sie klare Eingaben, klare Ausgaben und keine Nebeneffekte haben. Der Agent konnte die Funktion lesen, den Vertrag verstehen und umfassende Tests schreiben.

Komplexe Module mit Datenbankverbindungen, externen API-Aufrufen und geteiltem veränderlichem Zustand waren schwieriger. Der Agent generierte manchmal Tests, die zu viel mockten oder Implementierungsdetails statt Verhalten testeten. Das Team passte den Analyseschritt an, um reine Funktionen zuerst zu priorisieren und komplexe Module für manuelle Überprüfung einzureihen.

Bestehende Testbeispiele bereitstellen

Die einflussreichste Änderung war das Hinzufügen dieser Anweisung zur Aufgabenbeschreibung: “Lies bestehende Testdateien im selben Verzeichnis für Stilkonventionen.” Vor dieser Anweisung produzierte der Agent Tests, die funktional korrekt waren, aber andere Assertion-Muster, andere describe-Block-Strukturen und andere Namenskonventionen als der Rest der Test-Suite verwendeten. Nach der Anweisung waren generierte Tests kaum von handgeschriebenen zu unterscheiden.

Tests vor der PR-Erstellung ausführen

Frühe Iterationen des Workflows reichten PRs mit nicht verifizierten Tests ein. Einige hatten Import-Fehler, fehlende Fixtures oder Assertion-Fehler. Das Hinzufügen des npm test-Schritts innerhalb der Coding-Agent-Aufgabe — und die Anweisung, Fehler vor dem Abschluss zu beheben — eliminierte fast alle diese Probleme. Die iterative Schleife des Agenten (Test schreiben, Test ausführen, Fehler lesen, Test reparieren, erneut ausführen) entspricht genau der Arbeitsweise eines Menschen, nur schneller.

Auf Qualität prüfen, nicht nur auf Abdeckung

Abdeckung ist eine Proxy-Metrik. Ein Test, der expect(result).toBeDefined() bestätigt, deckt die Funktion technisch ab, überprüft aber nicht das Verhalten. Das Team fügte eine Review-Checkliste für generierte Test-PRs hinzu:

  • Überprüft jeder Test ein sinnvolles Verhalten, nicht nur, dass die Funktion läuft?
  • Sind Grenzfälle abgedeckt (null-Eingaben, leere Arrays, Grenzwerte)?
  • Beschreiben die Testbeschreibungen klar, welches Verhalten getestet wird?
  • Sind Assertions spezifisch (.toBe(42) nicht .toBeTruthy())?

Die meisten generierten Tests bestanden diese Checkliste ohne Änderungen. Die wenigen, die es nicht taten, waren leicht während des 12-Minuten-Reviews zu erkennen und zu beheben.

Die vollständige Konfiguration

Für Teams, die diesen Workflow replizieren möchten, hier die vollständige Schrittkonfiguration:

workflow:
  name: "Auto Test Generation"
  description: "Generate unit tests for untested code on PR merge"

  trigger:
    type: webhook
    source: github
    events: ["pull_request.closed"]
    filters:
      - field: "pull_request.merged"
        value: true
      - field: "pull_request.base.ref"
        value: "main"

  steps:
    - id: analyze-coverage
      type: recipe
      model: claude-sonnet-4-6
      # ... (siehe Schritt 2 oben)

    - id: generate-tests
      type: coding-agent
      model: claude-sonnet-4-6
      dependsOn: [analyze-coverage]
      # ... (siehe Schritt 3 oben)

    - id: submit-pr
      type: recipe
      model: claude-sonnet-4-6
      dependsOn: [generate-tests]
      # ... (siehe Schritt 4 oben)

Der Workflow läuft in 8-15 Minuten End-to-End, abhängig von der Anzahl der nicht getesteten Funktionen. Der Großteil der Zeit verbringt der Coding Agent mit dem Iterieren durch Testdateien und dem Ausführen von npm test nach jeder einzelnen.

Was kommt als Nächstes

Das Team erweitert den Workflow nun in zwei Richtungen:

  1. Integrationstests — ein separater Coding-Agent-Schritt, der Integrationstests für API-Endpunkte generiert, unter Verwendung bestehender Testhelfer und Datenbank-Fixtures
  2. Abdeckungsdurchsetzung — ein CI-Check, der den Build fehlschlagen lässt, wenn die Abdeckung unter 90% fällt, da die Basislinie jetzt hoch genug ist, um dies durchzusetzen

Die breitere Lektion: Testabdeckung muss keine manuelle Plackerei sein. Mit dem richtigen Workflow können Sie sie als automatisierte Pipeline behandeln, die neben Ihrem bestehenden CI/CD läuft — keine dedizierten Sprints, keine Deprioritisierung, keine Abdeckungsschulden.

Der Coding Agent ist in Pro-Tarifen und höher verfügbar. Bauen Sie Ihren ersten Coding-Workflow.

coding-agent case-study test-generation automation ci-cd
Diesen Artikel teilen

Hat Ihnen dieser Artikel gefallen?

Erhalten Sie Workflow-Tipps, Produktupdates und Automatisierungsleitfäden direkt in Ihren Posteingang.

No spam. Unsubscribe anytime.