# Unit-Tests mit KI schreiben: Leitfaden für Agenten

URL: https://agentvera.dev/de/blog/write-unit-tests-with-ai/ · Veröffentlicht: 2026-10-25

Unit-Tests mit KI-Agenten schreiben, die echte Bugs finden: Charakterisierungstests, Coverage-Lücken, Mutation Testing und ein Agent testet, während ein anderer baut.

**Kurz gesagt:**

- Ein KI-Agent schreibt Tests schnell, aber ein Test, der nur den gelesenen Code spiegelt, beweist nichts; verlange Verhalten aus der Spezifikation, nicht aus der Implementierung.
- Coverage zeigt dir ungetesteten Code, Mutation Testing zeigt dir schwache Tests: Eine Testsuite, die eine umgedrehte Bedingung überleben lässt, schützt dich nicht.
- Die Arbeit aufzuteilen funktioniert gut: Ein Agent schreibt die Tests, ein anderer den Code, und der Implementierer darf die Tests nicht ändern, damit sie grün werden.
- In AgentVera hält File Ownership den Implementierer aus dem Testordner heraus, Verify prüft das Ergebnis gegen deine Kriterien, und Checkpoints machen einen schlechten Turn rückgängig.

Wenn du Unit-Tests mit KI schreiben willst, ist der einfache Teil, überhaupt Tests zu bekommen. Bitte irgendeinen Coding-Agenten um „Tests für dieses Modul“, und nach ein paar Minuten hast du vierzig grüne Tests. Der schwierige Teil sind Tests, die fehlschlagen, wenn der Code falsch ist. Ein Agent, der eine Funktion liest und dann prüft, was genau diese Funktion zurückgibt, hat die Funktion im Wesentlichen ein zweites Mal geschrieben.

Dieser Leitfaden zeigt, wie du aus Coding-Agenten wie Claude Code, Codex oder Gemini CLI brauchbare Tests herausholst: was du verlangen solltest, wie du Tests erkennst, die nichts beweisen, wie du sie mit Coverage und Mutation Testing misst und wie du die Arbeit so aufteilst, dass der Agent, der den Code schreibt, die Tests nicht heimlich zurechtbiegen kann.

## Warum KI-geschriebene Tests schiefgehen

Agenten sind sehr gut in den mechanischen Teilen des Testens: Fixtures, Factories, Mocks, parametrisierte Fälle, das Grundgerüst einer neuen Testdatei. Wo sie danebenliegen, ist genau das, was einen Test wertvoll macht: der erwartete Wert.

Wenn ein Agent einen Test schreibt, hat er die Implementierung meist in seinem Kontext offen. Der naheliegende Schritt ist, den Code zu lesen, herauszufinden, was er zurückgibt, und genau das zu prüfen. Hat der Code einen Bug, schreibt der Test diesen Bug fest. Er ist grün, er deckt die Zeilen ab, und er bliebe grün, auch wenn du den Bug nie behebst.

Das tritt in ein paar typischen Formen auf:

- **Gespiegelte Logik.** Der Test berechnet den erwarteten Wert mit derselben Formel wie der Code: `expect(price(100, 0.2)).toBe(100 - 100 * 0.2)`. Ist die Formel falsch, sind beide gemeinsam falsch.
- **Das Testobjekt wird gemockt.** Was getestet werden soll, ist gemockt, also prüft der Test den Mock.
- **Nur Aufruf-Assertions.** `expect(sendEmail).toHaveBeenCalled()`, ohne zu prüfen, was an wen gesendet wurde.
- **Alles als Snapshot.** Ein riesiger Snapshot, den niemand liest und der mit `-u` aktualisiert wird, sobald er fehlschlägt.
- **Assertions, die nicht fehlschlagen können.** `expect(result).toBeDefined()` bei einer Funktion, die immer ein Objekt zurückgibt.
- **Den Test anpassen, bis er besteht.** Der Code fällt durch einen Test, und der Agent „repariert“ den erwarteten Wert des Tests statt des Codes.

Nichts davon ist KI-spezifisch. Menschen schreiben solche Tests auch. Agenten erzeugen sie nur schneller und in größeren Mengen, deshalb brauchst du einen Ablauf, der sie abfängt.

## Vom Verhalten ausgehen, nicht vom Code

Die mit Abstand größte Verbesserung: Sag dem Agenten, was der Code tun soll, und halte die erwarteten Werte von der Implementierung fern.

Ein schwacher Prompt:

> Schreib Unit-Tests für `src/billing/discount.ts`.

Ein besserer:

> Schreib Unit-Tests für `applyDiscount` in `src/billing/discount.ts`. Regeln: Ein prozentualer Rabatt drückt die Summe nie unter null; Rabatte werden nicht kombiniert, der größte gewinnt; ein abgelaufener Code wird ignoriert, ist aber kein Fehler; Beträge werden kaufmännisch auf 2 Nachkommastellen gerundet. Leite die erwarteten Werte von Hand aus diesen Regeln ab, nicht durch Ausführen oder Lesen der Implementierung. Wenn eine Regel dem aktuellen Code zu widersprechen scheint, schreib den Test trotzdem und sag mir, welche Tests fehlschlagen.

Drei Dinge haben sich geändert. Die Regeln kommen von dir, aus einem Ticket, einer Spezifikation oder der Dokumentation. Die erwarteten Werte sind Literale, die aus den Regeln abgeleitet sind. Und ein fehlschlagender Test ist erlaubt: Er könnte einen echten Bug zeigen, und genau dafür sind Tests da.

Ein paar weitere Gewohnheiten helfen:

- **Erst die Liste der Fälle.** „Liste die Fälle, die du testen willst, je eine Zeile, bevor du Code schreibst.“ So ergänzt du fehlende Randfälle (leere Eingabe, Unicode, Zeitzonen, die Grenze bei genau null), bevor überhaupt Code existiert.
- **Grenzen benennen.** Agenten finden Randfälle gut, wenn du auf die Dimension zeigst: „Eingaben genau an, knapp unter und knapp über jeder Grenze“.
- **Sagen, was nicht gemockt wird.** „Mocke nichts innerhalb von `src/billing`; mocke nur den HTTP-Client.“ Zu viel Mocking ist der Anfang vieler tautologischer Tests.
- **Ein Verhalten pro Test.** Tests mit einem klaren Namen wie `ignores_expired_codes` lassen sich leichter reviewen als ein Test mit zwölf Assertions.

## Unit-, Integrations- und End-to-End-Tests

Derselbe Agent kann alle drei Arten schreiben, aber die Anweisungen unterscheiden sich.

### Unit-Tests

Schnell, isoliert, viele davon. Hier spart ein Agent am meisten Zeit. Verweise ihn auf euren bestehenden Teststil („orientiere dich an `tests/billing/tax.test.ts`“), damit nicht jedes Mal eine neue Hilfsbibliothek entsteht. Schreib den Testbefehl in deine `CLAUDE.md` oder `AGENTS.md`, damit der Agent die Tests selbst ausführt; mehr dazu in [CLAUDE.md und AGENTS.md schreiben](/de/blog/claude-md-agents-md/).

### Integrationstests

Sie berühren eine echte Datenbank, Queue oder ein echtes Dateisystem. Agenten greifen hier gern zu Mocks, und dann wird aus dem Integrationstest wieder ein Unit-Test. Sei explizit: „Nutze die Testdatenbank aus `docker-compose.test.yml`; mocke die Repository-Schicht nicht.“ Verlange auch Aufräumen, damit Tests nicht von den Resten anderer Tests abhängen.

### End-to-End-Tests

Für Browsertests kann ein Agent Playwright- oder Cypress-Specs aus einem beschriebenen Nutzerablauf schreiben. Die Schwachstelle sind Selektoren: Verlange rollen- oder labelbasierte Selektoren (`getByRole('button', { name: 'Pay' })`) statt CSS-Pfaden, die beim nächsten Redesign brechen. Der Beitrag zu [Browsertests mit KI-Agenten](/de/blog/ai-agent-browser-testing/) zeigt, wie ein Agent einen echten Browser steuert, um seine eigene Arbeit zu prüfen.

## Charakterisierungstests für Code, den du noch nicht verstehst

Manchmal gibt es keine Spezifikation. Der Code ist alt, wer ihn geschrieben hat, ist weg, und niemand weiß genau, was er tut. Dann dreht sich das Ziel um: Du willst Tests, die festhalten, was der Code heute tut, Bugs inklusive, damit du merkst, wenn sich das ändert.

Das nennt man Charakterisierungstests, und hier ist es ausnahmsweise richtig, den Agenten die Implementierung lesen zu lassen. Der Prompt ändert sich entsprechend:

> Schreib Charakterisierungstests für `legacy/invoice_export.py`. Halte das aktuelle Verhalten fest, auch alles, was nach einem Bug aussieht; behebe nichts. Decke jeden Zweig ab, den du findest. Markiere Verhalten, das falsch wirkt, mit einem `# SUSPICIOUS:`-Kommentar und einer Begründung.

Die `SUSPICIOUS`-Notizen werden später deine Bugliste. Snapshot- oder Approval-Tests sind hier in Ordnung, solange sie klein genug zum Lesen sind. Das ist der erste Schritt jedes sicheren Refactorings, den der Leitfaden [Legacy-Code mit KI refactoren](/de/blog/refactor-legacy-code-with-ai/) Schritt für Schritt durchgeht.

## Coverage zum Finden von Lücken nutzen, nicht zum Benoten

Coverage ist eine gute Landkarte und eine schlechte Note. Nutze sie, um dem Agenten zu zeigen, wo er suchen soll:

| Stack | Befehl |
| --- | --- |
| Vitest | `npx vitest run --coverage` |
| Jest | `npx jest --coverage` |
| pytest (mit pytest-cov) | `pytest --cov=myapp --cov-report=term-missing` |
| Go | `go test -coverprofile=cover.out ./...` dann `go tool cover -func=cover.out` |

Vitest braucht einen installierten Coverage-Provider wie `@vitest/coverage-v8`. Der `term-missing`-Bericht von pytest listet die genauen nicht abgedeckten Zeilennummern, die du direkt in einen Prompt kopieren kannst.

Eine gute Schleife:

1. Coverage ausführen und die Module auswählen, auf die es ankommt: Abrechnung, Auth, Datenmigrationen, nicht generierter Code.
2. Dem Agenten die nicht abgedeckten Zeilen geben und fragen, welches Verhalten sie darstellen.
3. Ihn Tests für dieses Verhalten schreiben lassen, mit erwarteten Werten aus den Regeln.
4. Coverage erneut ausführen und bestätigen, dass die Zeilen jetzt durchlaufen werden.

Was du nicht tun solltest: „Bring die Coverage auf 90 %“ sagen. Ein Agent, der eine Zahl bekommt, erreicht die Zahl, und der billigste Weg dahin sind Tests, die Zeilen ausführen, ohne viel zu prüfen.

## Mutation Testing: Prüfen die Tests überhaupt etwas?

Mutation Testing beantwortet die Frage, die Coverage nicht beantworten kann. Ein Tool verändert deinen Code an kleinen Stellen, dreht etwa `>` zu `>=`, ersetzt `+` durch `-` oder gibt einen leeren Wert zurück, und lässt deine Tests gegen jede Änderung laufen. Bestehen die Tests trotzdem, hat der Mutant „überlebt“, und du hast eine Stelle gefunden, an der die Tests das Verhalten nicht wirklich prüfen.

Verbreitete Tools:

- **JavaScript und TypeScript:** StrykerJS. Einrichten mit `npm init stryker@latest`, dann `npx stryker run` ausführen.
- **Python:** mutmut. `mutmut run` ausführen, dann mit `mutmut browse` die überlebenden Mutanten durchgehen. Neuere Versionen brauchen Fork-Unterstützung, unter Windows läuft es daher in WSL.
- **Java:** PIT, zum Beispiel `mvn test-compile org.pitest:pitest-maven:mutationCoverage`.
- **Rust:** cargo-mutants, installiert mit `cargo install cargo-mutants` und ausgeführt mit `cargo mutants`.

Mutationsläufe sind bei großen Codebasen langsam, beschränke sie also auf das Modul, an dem du arbeitest. Dann gibst du die Überlebenden an den Agenten:

> Diese Mutanten haben in `discount.ts` überlebt: (Liste). Schreib für jeden einen Test, der beim Mutanten fehlschlägt und beim Original besteht. Ändere `discount.ts` nicht.

Das ist einer der besten Einsätze eines Agenten beim Testen. Die Aufgabe ist präzise, die Erfolgsprüfung mechanisch, und das Ergebnis ist ein Test, der nachweislich eine echte Art von Bug fängt.

## Ein Agent schreibt Tests, ein anderer den Code

Der zuverlässigste Weg, einen Agenten am Zurechtbiegen von Tests zu hindern: Der Agent, der den Code schreibt, kommt an die Tests gar nicht heran.

Der Aufbau ist einfach:

1. **Test-Agent.** Bekommt die Spezifikation und schreibt Tests in `tests/` (oder wo eure Tests liegen). Er sieht und schreibt die Implementierung nicht. Seine Tests sollten zuerst fehlschlagen, weil das Feature noch nicht existiert.
2. **Implementierer-Agent.** Bekommt dieselbe Spezifikation plus die fehlschlagenden Tests und schreibt Code, bis sie bestehen. Er darf nichts in `tests/` ändern.
3. **Meinungsverschiedenheiten gehen zurück.** Hält der Implementierer einen Test für falsch, fragt er den Test-Agenten oder dich, statt ihn zu ändern.

Das ist testgetriebene Entwicklung, verteilt auf zwei Agenten, und es funktioniert auch über Anbieter hinweg. Manche Teams lassen ein Modell die Tests schreiben und ein anderes implementieren, damit die beiden nicht dieselben blinden Flecken teilen.

Zwei Agenten am selben Feature brauchen etwas Isolation, damit sie sich nicht in die Quere kommen. Ein eigener [Git-Worktree](/de/glossary/git-worktree/) pro Agent ist die übliche Antwort; siehe [Git-Worktrees für parallele Agenten](/de/blog/git-worktree-parallel-agents/). Bei genau dieser Aufteilung kannst du beide auch in einem Worktree lassen, weil sie in verschiedene Ordner schreiben.

## KI-geschriebene Tests reviewen

Lies die Tests mindestens so sorgfältig wie den Code. Eine kurze Checkliste:

- **Kommen die erwarteten Werte aus den Regeln?** Achte auf Literale, nicht auf Formeln, die aus dem Code kopiert sind.
- **Würde dieser Test fehlschlagen, wenn der Code falsch wäre?** Nimm dir einen Test und mach den Code von Hand kaputt. Bleibt er grün, ist der Test Dekoration.
- **Ist etwas Wichtiges gemockt?** Mocks an der Systemgrenze sind in Ordnung, Mocks des getesteten Codes nicht.
- **Hat sich ein bestehender Test geändert?** In einem Feature-Branch verdienen geänderte erwartete Werte in alten Tests eine Nachfrage. `git diff --stat -- tests/` zeigt das auf einen Blick.
- **Sind die Namen lesbar?** Der Name eines fehlschlagenden Tests sollte sagen, was kaputt ist.
- **Ist er flaky?** Achte auf echte Uhrzeit, Zufallsdaten, Netzwerkaufrufe und Testreihenfolge. Lass den Agenten die neuen Tests mehrmals ausführen.

Automatisches Code-Review hilft auch hier. Ein zweites Modell, das den Diff liest, bemerkt oft einen Test, der nichts prüft. Wie das funktioniert, steht im Beitrag zum [KI-Code-Review](/de/blog/ai-code-review/).

## Häufige Fehler

- **„Schreib Tests für diese Datei“ und sonst nichts.** Du bekommst die Implementierung, nur noch einmal formuliert.
- **Einer Coverage-Zahl hinterherjagen.** Du bekommst ausgeführte Zeilen, kein geprüftes Verhalten.
- **Den Implementierer Tests ändern lassen.** Der schnellste Weg zu Grün ist eine geänderte Assertion.
- **Snapshots aktualisieren, ohne sie zu lesen.** `-u` macht aus einer Regression die neue erwartete Ausgabe.
- **Tests für Code schreiben, den du gleich löschst.** Teste das Verhalten, das bleibt.
- **Flaky Tests drinlassen.** Ein Agent, der einen flaky Test fehlschlagen sieht, „repariert“ gern etwas, das gar nicht kaputt war. Dasselbe gilt, wenn du [CI-Fehler mit KI beheben](/de/blog/auto-fix-ci-failures-with-ai/) lässt.

## So geht es in AgentVera

AgentVera führt Coding-Agent-CLIs pro Projekt nebeneinander aus, deshalb ist das Duo aus Test-Agent und Implementierer in ein paar Minuten eingerichtet.

- **Zwei Agenten, ein Feature.** Öffne einen Test-Agenten und einen Implementierer im selben Projekt, auf derselben CLI oder auf verschiedenen, etwa Claude Code für die Tests und Codex für den Code. Leg sie über das Worktree-Panel in einen eigenen Worktree, wenn die Arbeit nicht in deinem Hauptordner passieren soll.
- **File Ownership hält den Implementierer aus den Tests heraus.** Trag im Dialog des Test-Agenten `tests/**` bei seinen Bereichen ein. Solange er läuft, können andere Agenten diese Dateien nicht bearbeiten. Bei Claude-Code-Agenten wird die Änderung schon vorher von einem PreToolUse-Hook abgelehnt; Codex und andere CLIs bekommen die Regel in ihren Anweisungen. Abgelehnte Versuche erscheinen in der Team-Timeline.
- **Agent Messaging bei Meinungsverschiedenheiten.** Hält der Implementierer einen Test für falsch, kann er dem Test-Agenten direkt schreiben und auf die Antwort warten, statt den Test zu ändern.
- **Verify prüft das Ergebnis.** Schreib in deine Nachricht, was „fertig“ bedeutet, zum Beispiel „alle Tests in `tests/billing` bestehen und keine Testdatei wurde geändert“. Verify macht daraus Kriterien, und wenn der Turn des Agenten endet, führt ein separater Verifier die Tests aus und markiert jedes Kriterium mit einem Beleg. Der Verifier kann das Repo lesen und Testbefehle ausführen, aber keine Dateien bearbeiten.
- **Code-Review liest die Tests.** Das automatische Code-Review prüft die Änderungen jedes Turns mit dem Claude-Modell deiner Wahl und listet Befunde mit Schweregrad und Datei:Zeile, ein guter zweiter Blick auf schwache Assertions.
- **Checkpoints für schlechte Turns.** Jeder Turn wird als Snapshot gesichert. Schreibt ein Agent die halbe Testsuite in eine Richtung um, die dir nicht gefällt, machst du diesen Turn rückgängig und versuchst es neu. Siehe [Änderungen von Claude Code rückgängig machen](/de/blog/undo-claude-code-changes/).

## Fazit

KI macht das Schreiben von Tests billig, und damit verschiebt sich die Arbeit vom Tippen der Tests zum Beurteilen der Tests. Gib dem Agenten Verhalten statt Code, halte die erwarteten Werte von der Implementierung fern, nutze Coverage als Landkarte und Mutation Testing als Note, und lass nicht den Agenten, der den Code schreibt, auch entscheiden, was „bestanden“ heißt. Dann ist der Geschwindigkeitsgewinn echt: eine Testsuite, die schnell wächst und trotzdem fehlschlägt, wenn etwas kaputtgeht.

Mehr zum Thema:

- [Verify](/de/features/verify/)
- [File Ownership](/de/features/file-ownership/)
- [Agent Messaging](/de/features/agent-messaging/)
- [Code-Review](/de/features/code-review/)
- [Checkpoints und Replay](/de/features/checkpoints-and-replay/)
- [Parallele Coding-Agenten](/de/blog/parallel-coding-agents/)

Um AgentVera auszuprobieren, starte auf der [Startseite](/de/).

## Häufige Fragen

**Kann KI gute Unit-Tests schreiben?** Ja, wenn du sie lenkst. Agenten sind stark bei Setup, Fixtures, Listen von Randfällen und Boilerplate. Schwach sind sie, wenn sie die erwarteten Werte aus dem getesteten Code ableiten, denn dann wiederholt der Test nur die Implementierung. Gib ihnen das erwartete Verhalten vor und prüfe die Tests mit Mutation Testing.

**Was ist ein tautologischer Test?** Ein Test, der schon durch seinen Aufbau besteht: Er berechnet den erwarteten Wert genauso wie der Code, mockt genau das, was er prüfen soll, oder prüft nur, ob eine Funktion aufgerufen wurde. Er bleibt grün, auch wenn die Logik falsch ist.

**Sind 100 % Coverage ein gutes Ziel für KI-geschriebene Tests?** Nein. Coverage sagt dir, welche Zeilen ausgeführt wurden, nicht, ob irgendetwas geprüft wurde. Nutze sie, um ungetestete Bereiche zu finden, und bewerte die Tests dann mit Mutation Testing oder einem sorgfältigen Review.

**Sollte derselbe Agent Tests und Code schreiben?** Bei kleinen Änderungen ist das in Ordnung. Bei wichtiger Logik hilft die Aufteilung: Ein Agent schreibt Tests aus der Spezifikation, ein anderer implementiert, und der Implementierer darf die Tests nicht ändern. Das verhindert den einfachsten Trick, nämlich den Test so lange anzupassen, bis er besteht.

**Welche Agenten kann ich dafür in AgentVera nutzen?** Jeden CLI-Agenten, den AgentVera ausführt, etwa Claude Code, Codex oder Gemini CLI. File Ownership blockiert Änderungen bei Claude-Code-Agenten schon vorab; Codex und andere CLIs bekommen die Ownership-Regeln in ihren Anweisungen.

---

**Über AgentVera.** AgentVera ist eine Desktop-App für macOS, Windows und Linux, entwickelt von Solviera Teknoloji. Sie führt 18 KI-Coding-Agenten (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) nebeneinander aus, pro Projekt, in echten Terminals mit den eigenen CLI-Installationen und Logins des Nutzers. Der kostenlose Plan hat unbegrenzt viele Agenten. Download: https://agentvera.dev/de/download/ · Preise: https://agentvera.dev/de/pricing/
