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:
| Metrik | Wert |
|---|---|
| Start-Abdeckung | 60% |
| End-Abdeckung | 94% |
| Generierte Tests | 847 |
| Erstellte Pull Requests | 42 |
| Durchschnittliche PR-Review-Zeit | 12 Minuten |
| Tests, die bestehende Bugs fanden | 23 |
| 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:
- Integrationstests — ein separater Coding-Agent-Schritt, der Integrationstests für API-Endpunkte generiert, unter Verwendung bestehender Testhelfer und Datenbank-Fixtures
- 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.