Zum Inhalt springen

Red-Green-TDD mit KI-Agenten: erst muss der Test scheitern

Für CTOs und EntwicklerHarness und Prüfungen · Aktualisiert

Filip PapranecGründer von Digitaliko

Ein Test, der auf dem alten Code besteht, beweist nichts. Illustration: derselbe Test zweimal ausgeführt, rot auf dem Basis-Branch und grün auf dem Feature-Branch.Ein Test, der auf dem alten Code besteht, beweist nichts. Illustration: derselbe Test zweimal ausgeführt, rot auf dem Basis-Branch und grün auf dem Feature-Branch.

KI-Agenten schreiben Tests, die bestehen. Das sind nicht automatisch Tests, die etwas beweisen, und ein Senior, der beides im Review auseinanderhalten muss, verliert die Zeit, die KI sparen sollte. Deshalb führt unser Gate jeden neuen Test zuerst gegen den alten Code aus. Besteht er auch dort, ist der PR rot.

Das ist Red-Green-Refactor, erzwungen von einer Maschine statt von Disziplin. KI schreibt heute unseren gesamten Code, und ein Senior steht für das Ergebnis gerade. Red-Proof ist der Grund, warum dieser Senior einem grünen Check trauen kann.

Warum sind KI-geschriebene Tests ein Risiko?

Bitten Sie einen Agenten, „Tests hinzuzufügen“, und Sie bekommen Tests, die grün werden. Ohne klare Vorgabe schreibt er sie nach dem Code und entlang des Codes, sodass sie bestätigen, was der Code ohnehin tut. Manche rufen den Code nicht einmal auf. Wir haben Tests gesehen, die eine Quelldatei als Text lasen und nach einem Funktionsnamen suchten. Sie bestehen auf jeder Version, die dieses Wort enthält.

Die Abdeckung steigt. Der Beweis bleibt, wo er war. Der Reviewer wird zur letzten Verteidigungslinie, und jeden Test genau zu lesen ist genau die Arbeit, die Sie loswerden wollten.

Wo steht Ihr Team?

Was ist Red-Proof?

Der rote Schritt von Red-Green-Refactor, geprüft von einem Skript:

  1. Red. Der neue Test muss auf dem Basis-Branch scheitern, also auf dem Code vor der Änderung.
  2. Green. Derselbe Test muss auf dem Branch bestehen.
  3. Kein Test, keine Änderung. Geänderter Quellcode ohne geänderten Test ist ein Fehler.
Red-Proof am Beispieltest „Rabatt gilt nur einmal“: Der Agent committet nur den Test, auf dem Basis-Branch main scheitert der Test (FAIL), auf dem Branch mit der Änderung besteht er (PASS). Bestünde er auch auf main, ist der PR rot.Red-Proof am Beispieltest „Rabatt gilt nur einmal“: Der Agent committet nur den Test, auf dem Basis-Branch main scheitert der Test (FAIL), auf dem Branch mit der Änderung besteht er (PASS). Bestünde er auch auf main, ist der PR rot.

Die Vorgabe, die unser Agent für Code-Aufgaben bekommt, sagt dasselbe in Worten. Schreibe einen Test für das riskanteste Kriterium und committe ihn allein. Er muss auf dem unveränderten Code scheitern. Dann implementiere. Ändere den Test nach seinem Commit nicht mehr.

Worte sind eine Bitte. Das Gate ist das Schloss.

Wie prüft das Gate das?

Es ist schlichtes Bash, gate.sh in unserem Agenten-Harness. Der Kern, gekürzt:

# red-proof: the branch's new/changed tests must FAIL on the base code, or they prove nothing
changed=$(git diff --name-only "$base"...HEAD; git ls-files --others --exclude-standard)
tests=$(printf '%s\n' "$changed" | grep -E '(^|/)(tests?|__tests__|spec)/|\.(test|spec)\.[a-z]+$')
src=$(printf '%s\n' "$changed" | grep -E '\.(ts|tsx|js|jsx|mjs|py|go|rs|php|rb)$' \
      | grep -vE '(^|/)(tests?|__tests__|spec)/|\.(test|spec)\.')
if [ -z "$tests" ]; then
    [ -n "$src" ] && echo "FAIL red-proof: source changed but no test was added or changed"
else
    cmd=$(jq -r .scripts.test package.json)
    git worktree add -q --detach "$W/base" "$base"      # the old code, next to the branch
    for t in $tests; do cp "$t" "$W/base/$t"; done      # the new tests, onto the old code
    if (cd "$W/base" && sh -c "$cmd") > "$W/red-test.log" 2>&1; then
        echo "FAIL red-proof: the new tests also pass on $base, so they do not prove the change"
    else
        echo "PASS red-proof: new tests fail on $base and pass on the branch"
    fi
fi

Drei Regeln stehen drumherum:

  • Tests ohne test-Skript sind ein Fehler. Nichts würde sie ausführen.
  • Der Reviewer liest, warum die Tests auf der Basis scheiterten. Das Gate gibt die ersten Assertions aus dem roten Lauf aus. Ein Scheitern wegen einer fehlenden Datei oder eines fehlenden Imports ist kein roter Beweis, und der Reviewer sagt das.
  • Tests, die Quellcode als Text lesen, gehen zurück. Die Anweisungen des Reviewers nennen sie beim Namen: Ein Test muss die Funktion aufrufen, die Komponente rendern oder die Route anfragen.

Das Gate heißt nicht, dass mehr Tests besser sind. Überflüssige Tests löschen wir. Manchmal muss man vereinfachen, nicht nur hinzufügen.

Was kaputtging: ein falsches PASS auf rotem main

Die erste Version hatte ein Loch. Wenn der Basis-Branch schon an seiner eigenen Testsuite scheiterte, sah jeder neue Test dort rot aus. Das Gate meldete PASS für Tests, die nichts bewiesen.

Der Fix: Scheitert die Suite auf der Basis bereits, laufen nur die neuen Testdateien einzeln. Auf der Basis müssen sie scheitern, auf dem Branch bestehen. Lassen sie sich nicht einzeln ausführen, ist das Ergebnis nicht aussagekräftig, und nicht aussagekräftig ist ein Fehler.

scoped=""
(cd "$W/base" && sh -c "$cmd") > "$W/base-test.log" 2>&1 || scoped=" $(echo $tests)"

Das zweite Loch war die Umgebung. Auf einem unserer Projekte startete Red-Proof die Tests ohne die richtige Umgebung: Ein Tool fehlte (turbo: command not found), und eine andere Node-Version lief. Die Tests auf der Basis scheiterten, bevor sie überhaupt liefen. Das Gate wertete das als roten Beweis, also war dort jedes Red-Proof ein falsches PASS.

Derselbe Fix hat die Screenshots verschärft. Eine sichtbare UI-Änderung bestand früher mit irgendeinem angehängten PNG. Jetzt braucht sie ein Vorher und ein Nachher.

Braucht jede Änderung einen roten Test?

Nein. Ein reines Refactoring oder eine Konfigurationsänderung hat nichts Neues zu beweisen. Alles andere geht durch das Gate:

ÄnderungRed-ProofWer entscheidet
Neue Funktion oder BugfixJa. Der neue Test scheitert auf dem Basis-Branch und besteht auf dem Branch.Das Gate
Quellcode-Änderung ohne TestFehler, der PR ist rot.Das Gate
Reines Refactoring oder KonfigurationKann ausgenommen werden: Label skip-red-proof in unserem öffentlichen Starter.Ein Mensch, nie der Agent
Sichtbare UI-ÄnderungZum Test noch ein Screenshot vorher und nachher.Das Gate und der Reviewer

Umgekehrt gilt das für kritische Software, die Preise berechnet oder über Menschen entscheidet. Dort schalten wir das Gate nie ab.

Es ist ein Unterschied, ob Sie eine App einfach so vibe-coden oder etwas Kritisches bauen. Auch wenn ein Agent den Code schreibt, brauchen Sie dort die Tests und alle Gates.

Filip Papranec
Filip Papranec
Gründer von Digitaliko

Wie bringt man Red-Proof in die eigene CI?

Dasselbe Gate steckt in unserem öffentlichen Claude Code Production Starter, MIT-Lizenz. Führen Sie es lokal aus, bevor Sie „fertig“ sagen:

bash scripts/gate.sh all origin/main

Die Reihenfolge, die wir empfehlen:

  1. Zuerst der Test

    Der Agent schreibt einen Test für das riskanteste Kriterium und committet ihn allein.

  2. Gate lokal

    Vor „fertig“ läuft gate.sh gegen origin/main.

  3. Job in der CI

    Ein eigener red-proof-Job auf jedem Pull Request.

  4. Ausnahmen gibt ein Mensch

    Das Label skip-red-proof nur für reines Refactoring oder Konfiguration.

Der Starter enthält die einfachere Version ohne den Einzellauf der neuen Dateien, halten Sie Ihren Hauptzweig also grün. Das ist ohnehin ein guter Rat.

Regeln wie „ein Test muss zuerst scheitern“ gehören ins Repository, nicht in den Kopf eines Seniors. Mehr dazu in Regeln für KI-Code im Team. Warum die Checks um das Modell wichtiger sind als das Modell, steht in Harness Engineering in der Praxis: vom Issue zum PR.

Möchten Sie KI-Tests, die etwas beweisen?

Wir richten solche Gates direkt im Repository eines Teams ein im Rahmen von AI-native SDLC für Entwicklerteams. Fehlen Ihrem Team eher Hände als Regeln? Sehen Sie sich einen Senior-Entwickler für Ihr Team an. Seit 2023 haben wir 15+ Produktionsprojekte geliefert. Ein Senior arbeitet ab dem ersten Tag in Ihrem Repository und Ihren Pull Requests.

Wir melden uns innerhalb von zwei Arbeitstagen und wählen gemeinsam, was wir zuerst lösen.

Wenn Sie lieber zuerst sprechen möchten, buchen Sie ein 15-Minuten-Meeting mit Filip.

Welche Ihrer Tests würden noch bestehen, wenn Sie das Feature löschten?

Kurz gesagt

  • Ein Test, der vor und nach der Änderung besteht, beweist die Änderung nicht.
  • Red-Proof: Der neue Test muss auf dem Basis-Branch scheitern und auf dem Branch bestehen.
  • Das prüft ein Skript in der CI, keine Disziplin. Ausnahmen gibt nur ein Mensch.
  • Scheitert main schon, laufen die neuen Testdateien einzeln. Nicht aussagekräftig ist ein Fehler.

Häufige Fragen

Was ist Red Green Refactor?

Ein Zyklus der testgetriebenen Entwicklung: einen Test schreiben, der scheitert (red), den Code schreiben, mit dem er besteht (green), dann aufräumen (refactor). Der rote Schritt beweist, dass der Test das neue Verhalten prüft.

Wie funktioniert testgetriebene Entwicklung mit KI-Agenten?

Der Agent schreibt zuerst einen Test und committet ihn allein, erst dann implementiert er. Erzwingen Sie das in der CI: Der neue Test muss auf dem Basis-Branch scheitern und auf dem Branch bestehen. Sonst ist der PR rot.

Warum muss ein neuer Test auf dem Basis-Branch scheitern?

Ein Test, der vor und nach der Änderung besteht, testet die Änderung nicht. Vielleicht testet er gar nichts oder nur Verhalten, das es schon gab.

Was, wenn der Hauptzweig schon fehlschlagende Tests hat?

Dann scheitert die ganze Suite auf dem Basis-Branch, und jeder neue Test sieht rot aus. Führen Sie nur die neuen Testdateien einzeln aus. Lassen sie sich nicht einzeln ausführen, werten Sie das Ergebnis als Fehler, nicht als Erfolg.

Kann ein Agent Red-Proof überspringen?

Nicht allein. Ein reines Refactoring oder eine Konfigurationsänderung kann ausgenommen werden, aber das entscheidet ein Mensch, mit einem Label am Pull Request.

Fragen Sie eine KI zu diesem Artikel

Die KI nutzt dabei auch unsere anderen Artikel und Erfahrung aus echten Projekten.

ChatGPTClaudePerplexity
Engineering

Weitere Artikel

Harness und Prüfungen

Playwright MCP: Der KI-Agent beweist es im Browser

Playwright MCP gibt einem KI-Agenten einen echten Browser. Wie wir ihn nutzen, damit der Agent seine eigene Änderung in der laufenden App prüft und PASS oder FAIL mit Screenshots zurückgibt, was das findet, was Unit-Tests übersehen, und wann einfache Playwright-Skripte besser sind.

Harness und Prüfungen

LLM as a Judge: KI-Reviewer, der die Arbeit widerlegen soll

LLM as a Judge heißt: Ein Sprachmodell bewertet die Arbeit eines anderen Modells anhand schriftlicher Kriterien. Wie wir das bei jedem Pull Request unseres KI-Agenten einsetzen: zuerst maschinelle Checks, dann eine frische Session nur mit Lesezugriff, die widerlegen soll, ein typisiertes Urteil und die Regeln, die nach seinen Fehlern dazukamen.

Harness und Prüfungen

KI-Code-Review mit Claude Code in CI: was es übersieht

Wie wir Claude Code Review auf jedem Pull Request mit einer wiederverwendbaren GitHub Action betreiben: was der KI-Reviewer suchen soll, wie er grün blieb und schwieg, was er übersieht und warum nur ein Mensch freigibt.

Zeit, mit dem Planen aufzuhören und das Problem zu lösen.

Kontakt

  • Digitaliko s.r.o.
    Šípková 377/17
    958 03 Malé Uherce, Slowakei
  • Melden Sie sich bei uns
    info@digitaliko.com
    +421 950 595 506
    WhatsApp