Beliebte Suchanfragen
//

Kein Schummeln erlaubt: Isolierte Specification Tests mit Claude Code

2.3.2026 | 10 Minuten Lesezeit

KI-Agenten sind leistungsfähig — aber sie schummeln, wenn man sie lässt. Wer denselben Agenten entwickeln und testen lässt, riskiert, dass er nicht mehr die Spezifikation erfüllt, sondern nur noch die Tests besteht. Dieser Artikel zeigt, wie man das verhindert — und nebenbei lernen wir auch eine konkrete Anwendung eines MCP-Servers sowie den Einsatz eigener Slash Commands in Claude Code kennen.

Als Einstieg lohnt ein kurzer Blick auf die fünf Stufen der KI-gestützten Entwicklung.

Viele Software-Entwickler bewegen sich aktuell vermutlich irgendwo zwischen Stufe 2 und Stufe 3 — und Stufe 3 ist dabei evtl. sogar die optimistische Einschätzung. Auf Stufe 2 ist es durchaus berechtigt zu fragen, ob KI die Entwicklung überhaupt beschleunigt. Es mag sich schneller anfühlen, aber Code-Reviews, manuelle Tests und ständiges Context-Switching können die eingesparte Zeit schnell wieder auffressen.

Zeit, den Sprung auf Stufe 4 zu wagen — und Specification Testing mit Claude Code ist hoffentlich ein hilfreicher Schritt in diese Richtung.

Die Beispiel-Anwendung aufsetzen

Die Zeiten, in denen das Aufsetzen einer Beispiel-Anwendung Stunden an Scaffolding, Config-Dateien und Stack Overflow-Seiten bedeutete, sind glücklicherweise vorbei. Das gesamte Setup für dieses Projekt wurde mit einem einzigen Prompt in Claude Code generiert — und dieser Prompt selbst entstand aus einem noch kürzeren, dank Sonnet 4.6.

Schauen wir, ob das KI-Versprechen hält. Dafür verwenden wir Claude Opus 4.6 — Anthropics leistungsfähigstes Modell zum Zeitpunkt dieses Artikels.

💡 Tipp Eine Desktop-Version von Claude Code ist für macOS verfügbar, ich bleibe jedoch beim Terminal, um dies für alle zugänglich zu halten — und ich muss sagen, das Terminal hat dabei seinen ganz eigenen Charme.

Mit dieser Spezifikation — die letztlich nichts anderes als ein sorgfältig ausgearbeiteter Prompt ist — kann die vollständige Beispielanwendung in einem Durchgang generiert werden. Die CLAUDE.md-Datei des Coding-Agenten ist ebenfalls im Repository verfügbar — zusammen mit allen anderen Konfigurationsdateien und Szenarien, auf die in diesem Artikel verwiesen wird.

Fünf Minuten später! Ok, sechs Minuten und 28 Sekunden später.

Eine Login-Seite, vollständig mit Passcode-Validierung verdrahtet — out of the box.

Und nach Eingabe des korrekten Passcodes erscheint unsere fiktive Portfolio-Homepage. Dies wird unser Spielfeld für Specification Testing mit Claude Code.

Claude Code: Playwright MCP-Server

Playwright ist heute eines der beliebtesten Frameworks für die Implementierung von Frontend-Tests. Es automatisiert echte Browser-Interaktionen — Navigation, Klicks, Formulareingaben, Screenshots — und ist damit die ideale Grundlage für einen KI-gestützten Testing-Agenten.

Die Playwright-Integration für Claude Code kommt als MCP-Server. Einfach die folgende Datei in das entsprechende Stammverzeichnis des Projekts legen — direkt neben die CLAUDE.md-Datei. Oder noch einfacher: Einfach Claude Code bitten, die entsprechende Datei zu erzeugen.

1// .mcp.json
2{
3  "mcpServers": {
4    "playwright": {
5      "type": "stdio",
6      "command": "npx",
7      "args": ["@playwright/mcp@latest"],
8      "env": {}
9    }
10  }
11}

Eine der vielen praktischen Eigenschaften von KI-Tools wie Claude Code ist die Möglichkeit, einfach nachzufragen, ob etwas funktioniert.

Das scheint nicht zu funktionieren — doch keine Panik. Manche Dinge ändern sich auch im Zeitalter der KI nicht. Wir müssen Claude Code neu starten, damit die neue Datei eingelesen wird.

Nach dem Neustart wird der MCP-Server sofort erkannt.

Zur Sicherheit — und weil es Spaß macht — fragen wir noch einmal nach.

Sehr gut. Wir können loslegen.

Separation of Concerns — Der Testing-Agent

Damit kommen wir zum Kern dieses Artikels. Es ist entscheidend, dass der Agent, der die Anwendung testet, strikt vom implementierenden Agenten getrennt ist.

Der Grund ist einfach: Ohne diese Trennung könnte der Coding-Agent beginnen, sein Verhalten auf die Testszenarien hin zu optimieren — statt die eigentliche Spezifikation zu erfüllen. Beide Artefakte beschreiben dasselbe Verhalten, dienen aber entgegengesetzten Zwecken: Die Szenarien definieren exakte Schritte und erwartete Ergebnisse, die Spezifikation formuliert Absichten und Rahmenbedingungen.

Diese Trennung kann natürlich durch zwei vollständig separate Git-Repositories erreicht werden — für kleine bis mittlere Projekte ist dieser Overhead jedoch selten gerechtfertigt.

Der entscheidende Mechanismus, um dies ohne getrennte Repositories zu erreichen: die .claudeignore-Datei.

Ähnlich wie eine .gitignore-Datei sorgt sie dafür, dass Claude Code bestimmte Verzeichnisse des Projekts ignoriert. Wenn die Tests in einem qa/-Unterverzeichnis liegen, genügt eine .claudeignore-Datei mit folgendem Inhalt:

qa/

Nun kann der Claude Code Testing-Agent aus dem qa/-Verzeichnis gestartet werden — und das ergibt genau das, was wir wollen: zwei Agenten mit vollständig getrennten Kontexten.

Werfen wir einen kurzen Blick auf die Verzeichnisstruktur des Testing-Agenten.

qa/
├── .mcp.json              # Playwright MCP-Server Konfiguration
├── .claude/
│   └── settings.json      # Berechtigungseinschränkungen
├── CLAUDE.md              # QA-Kontext und Anweisungen
├── scenarios/
│   ├── SC-001_login.feature
│   └── SC-002_home.feature
└── reports/               # Testergebnisse

Dieser hat eine eigene CLAUDE.md-Datei mit Anweisungen für den Testing-Agenten. Diese unterscheiden sich natürlich grundlegend von denen des Coding-Agenten. Die .mcp.json liegt ebenfalls hier, da nur der Testing-Agent Zugriff auf den Playwright MCP-Server benötigt. Der Coding-Agent kann selbstverständlich eine eigene MCP-Konfiguration haben.

Die settings.json-Datei stellt sicher, dass der Testing-Agent nicht in der Verzeichnisstruktur aufwärts navigiert und damit versehentlich den Quellcode des Projekts liest. Die szenariobasierten Tests sind als Blackbox-Tests konzipiert.

1{
2  "permissions": {
3    "allow": [
4      "Read(qa/**)",
5      "Write(qa/reports/**)"    
6    ],
7    "deny": [
8      "Read(../src/**)"
9    ]
10  }
11}

Fassen wir die Trennung der beiden Agenten in einer kurzen Tabelle zusammen.

Coding-AgentTesting-Agent
Gestartet vonproject-root/qa/
CLAUDE.mdCoding-KontextQA-Kontext
Liestspecs/, src/Nur qa/scenarios/
Schreibtsrc/qa/reports/
ToolsDateisystem, ShellPlaywright MCP, Dateisystem
ZielSpezifikation implementierenImplementierung validieren
Kennt TestsKein ZugriffJa
Kennt QuellcodeJaKein Zugriff

Ohne diese technische Isolation besteht die Gefahr, dass ein Coding-Agent nicht mehr die Spezifikation erfüllt — sondern nur noch die Tests besteht. Die Isolation ist daher nicht nur eine architektonische Entscheidung, sondern eine Notwendigkeit.

Letztlich ergibt das zwei spezialisierte Agenten — jeder mit einem bewusst eingeschränkten Blick auf das System. Kein Agent hat das vollständige Bild, und das ist beabsichtigt. Der Coding-Agent weiß, was zu bauen ist, aber nicht, wie es verifiziert wird. Der Testing-Agent weiß, wie zu verifizieren ist, kennt aber keine Implementierungsdetails. Das einzige gemeinsame Artefakt ist die laufende Anwendung selbst — auf die der Testing-Agent ausschließlich über den Browser zugreift.

Dies ist das KI-Äquivalent der klassischen Trennung zwischen Implementierung und Validierung — mit dem Unterschied, dass diese Trennung hier technisch erzwungen wird und nicht von Prozessen oder Disziplin abhängt.

Der Testing-Agent

Jetzt, da wir eine laufende Anwendung und einen separaten Testing-Agenten haben, müssen wir diesem Agenten eine klar definierte Rolle und entsprechende Einschränkungen geben.

Den Agenten nach seiner eigenen Rolle zu fragen liefert ein beruhigendes Ergebnis:

Wer mit Claude Code vertraut ist, weiß bereits, dass dieses Verhalten über die CLAUDE.md-Datei konfiguriert wird. Und natürlich schreiben wir diese Datei nicht manuell. Wir geben unsere Absicht an das Modell unserer Wahl (hier: Sonnet 4.6) und lassen es die Detailarbeit erledigen. Weitere Prompts können zur Feinabstimmung des Ergebnisses genutzt werden.

Es lohnt sich, diese Datei sorgfältig zu lesen, da sie das Verhalten des Testing-Agenten in wesentlichem Maße definiert.

Drei Aspekte der Agenten-Anweisungen sind besonders hervorzuheben:

  • „Berichte ausschließlich, was du beobachtest" ist die wichtigste Anweisung für einen Testing-Agenten. Ohne sie neigt Claude dazu, zu schlussfolgern oder anzunehmen — genau das Verhalten, das in einem Testkontext unterdrückt werden soll.

  • „Markiere ein Szenario nicht als bestanden, wenn nicht alle Bedingungen explizit verifiziert wurden" — dies adressiert die subtile LLM-Tendenz, Ergebnisse zu optimistisch zu bewerten. Die Anweisung erzwingt ein binäres, ehrliches Ergebnis.

  • „Session-Reset zwischen Szenarien" ist explizit, weil Claude Code dies nicht automatisch tut — und gemeinsamer Session-State ist eine der häufigsten Quellen für False Positives in E2E-Tests.

Das erste Szenario

Starten wir direkt mit der Ausführung des ersten Szenarios — die Definition schauen wir uns gleich im Anschluss an:

Run all scenarios in qa/scenarios/SC-001_login.feature and write the report to qa/reports/.

Claude Code beginnt dann seine Arbeit. Der Browser öffnet sich — der Headless-Modus ist hier selbstverständlich auch möglich — und der Agent fragt nach Genehmigungen für bestimmte Aktionen.

Dies ist das Ergebnis:

Und hier ist die Szenariodatei, mit der die Tests ausgeführt werden. Einfacher geht es kaum.

Feature: Login Page Access Control
The application must be protected by a code-based login page.
Only users entering the correct passcode may access protected pages.

Background:
Given I navigate to "http://localhost:4321"

Scenario: Successful login with correct passcode
Given I am on the login page
When I enter passcode "1711"
And I submit the login form
Then I should be redirected to "/home"
And I should see the heading "Thomas Jaspers"

Scenario: Login rejected with incorrect passcode
Given I am on the login page
When I enter passcode "0000"
And I submit the login form
Then I should remain on the login page
And I should see an error message
And the passcode input should be empty

Scenario: Direct navigation to protected page without session
Given I have no active session
When I navigate directly to "/services"
Then I should be redirected to the login page

Scenario: Session persists across page navigation
Given I have logged in with passcode "1711"
When I navigate to "/services"
And I navigate to "/contact"
Then I should not be redirected to the login page

Wer schon einmal Frontend-Tests manuell geschrieben hat, kennt das Problem: mühsam, fehleranfällig und schwer zu warten. Mit diesem agentischen Ansatz formulieren wir Tests einfach in natürlicher Sprache und überlassen dem Agenten die eigentliche Arbeit. Und das Beste daran: Solange sich das nach außen sichtbare Verhalten der Anwendung nicht ändert, müssen auch die Szenarien nicht angepasst werden — egal wie sehr sich die darunterliegende Implementierung ändert bzw. weiterentwickelt. Eine erhebliche Erleichterung für jeden Entwickler, der schon einmal eine fragile Test-Suite gewartet hat.

Es gibt zudem einen komfortableren Weg, die Testausführung anzustoßen.

Wiederholte Testausführung mit Commands

Als Nächstes brauchen wir einen komfortableren Weg, Tests wiederholt auszuführen — idealerweise etwas, das jeder im Team auslösen kann, ohne die vollständige Prompt-Syntax zu kennen.

Dafür erstellen wir einen Slash-Command. Wir legen eine neue Datei run-scenario.md in qa/.claude/commands/ an:

Execute the test scenarios in the specified feature file using Playwright MCP. Run each scenario independently with a fresh browser session. Write the results to qa/reports/ using the report template from CLAUDE.md.

Arguments: $FEATURE_FILE

Nach dem Neustart von Claude Code können wir nun einfach /run-scenario SC-001_login.feature aufrufen. Sauber und wiederholbar.

Fehlschlagende Tests

Nun wollen wir absichtlich einen fehlschlagenden Test einführen, um zu verifizieren, dass der Testing-Agent Fehler tatsächlich erkennt.

Dafür fügen wir der Feature-Datei das folgende Szenario hinzu — eines, das bewusst widersprüchlich ist: Ein korrekter Passcode darf niemals zu einer Fehlermeldung führen oder den Nutzer auf der Login-Seite belassen.

Scenario: Intentionally failing
Given I am on the login page
When I enter passcode "1711"
And I submit the login form
Then I should remain on the login page
And I should see an error message
And the passcode input should be empty

Wie erwartet markiert der generierte Report den Test klar als fehlgeschlagen:

💡 Tipp Claude Code liest Änderungen an Szenariodateien möglicherweise nicht sofort ein, da Dateiinhalte im Session-Kontext vorgehalten werden. Die zuverlässige Lösung ist ein Neustart des Agenten nach Änderungen an einer der Szenariodateien. Für eine elegantere Lösung kann das Kommando auch um eine entsprechende Anweisung erweitert werden:

Always re-read the feature file from the project directory before executing any scenarios.

Der Agent hat den Fehler gefunden, präzise dokumentiert und gemeldet — ohne manuellen Eingriff. Genau dafür ist dieser Ansatz gedacht.

Zusammenfassung

Wir haben gesehen, wie zwei dedizierte Claude Code-Agenten eingerichtet werden — einer für das Coding, einer für das Testing — und wie ein Projekt so strukturiert wird, das beide strikt voneinander isoliert arbeiten. Diese Isolation ist das Kernprinzip des Ansatzes und basiert auf drei Säulen:

  • Die .claudeignore-Datei verhindert, dass der Coding-Agent das qa/-Verzeichnis und seine Testszenarien liest.
  • Die settings.json-Berechtigungseinschränkungen verhindern, dass der Testing-Agent in den Produktions-Quellcode navigiert.
  • Dedizierte CLAUDE.md-Dateien geben jedem Agenten eine klar definierte Rolle, einen Geltungsbereich und klare Rahmenbedingungen.

Der Grund, warum diese Trennung wichtig ist: Der Coding-Agent darf nicht wissen, wie die Tests durchgeführt werden — dieses Wissen führt zu Optimierungs-Bias statt zu echter Spezifikationskonformität. Der Testing-Agent darf nichts über die Implementierung wissen — nur dann kann er eine echte Blackbox-Validierung ausschließlich auf Basis des beobachtbaren Verhaltens durchführen.

Wir haben auch gesehen, wie der Playwright MCP-Server dem Testing-Agenten echten Browser-Zugriff verschafft, wie in Gherkin-Syntax geschriebene Testszenarien vom Agenten als High-Level-Szenarien ausgeführt werden können, und wie Claude Code Custom Slash Commands die wiederholte Testausführung so einfach machen wie /run-scenario SC-001_login.feature.

Eines ist sicher: Szenariobasiertes Testen von Webanwendungen war noch nie so zugänglich wie heute.

Ausblick

Wir leben in einer schnelllebigen Zeit — und die Entwicklung wird sich von hier aus weiter beschleunigen. Die nächste Generation von Modellen wird bestehende Agenten-Setups leistungsfähiger machen, ohne dass Änderungen an der in diesem Artikel beschriebenen Architektur erforderlich sind.

Das Testing-Setup lässt sich selbstverständlich in eine CI/CD-Pipeline integrieren — und schließt damit den Kreis in einer vollständig agentischen Entwicklungs-Pipeline.

Das ist der eigentliche Gewinn: Die Ausführung übernehmen die Agenten, die Entscheidungen bleiben beim Team. Die Spezifikation ist dabei die Brücke zwischen beidem.

Beitrag teilen

//

Weitere Artikel in diesem Themenbereich

Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.

//
Jetzt für unseren Newsletter anmelden

Alles Wissenswerte auf einen Klick:
Unser Newsletter bietet dir die Möglichkeit, dich ohne großen Aufwand über die aktuellen Themen bei codecentric zu informieren.