rules.md und AGENTS.md strukturieren
So nutzt und teilst du AGENTS md und CLAUDE md richtig: Best Practices, Nested Files und Anti Patterns für Rules Dateien im KI Coding 2026 von Never Code Alone
Mehr erfahren
Cypress Custom Commands sind eigene Befehle, die du mit Cypress.Commands.add registrierst und danach wie cy.get oder cy.visit in jedem Test aufrufst. Sie bündeln wiederkehrende Abläufe wie Login, Selektoren oder Setup Schritte an einer Stelle.
Du legst sie meist in cypress/support/commands.js oder commands.ts ab. Die Support Datei lädt vor jedem Spec, deshalb stehen die Commands überall bereit. Mit Cypress.Commands.overwrite änderst du außerdem das Verhalten eingebauter Befehle, etwa um Passwörter im Log zu verbergen.
Gut gebaut sind Custom Commands mehr als eine Abkürzung. Sie sind die gemeinsame Sprache deiner Suite. Wer cy.login liest, weiß sofort, was passiert. Und wer einen neuen Test schreibt, ob Mensch oder KI Agent, nutzt dieselben geprüften Bausteine statt jedes Mal neu zu erfinden, wie man sich anmeldet.
Cypress mit Cypress Cloud nutzen wir täglich in Production. Roland Golla ist offizieller Cypress Ambassador, arbeitet seit über zwanzig Jahren an Testing und Refactoring und baut bei NCA seit 2013 automatisierte Tests. Custom Commands schreiben wir nicht nur für Projekte, wir pflegen sie auch als Open Source: Das NCA TESTIFY Cypress Plugin ist eine Sammlung genau solcher Commands, unter MIT Lizenz.
Passend dazu: der Cypress Workshop mit Roland Golla, die Cypress Remote Schulung für Teams, die Vibe Coding Beratung für Teams mit KI Agenten, unser Leitfaden zu rules.md und AGENTS.md und der Artikel zu Quality Gates für KI Code.
Ein Tag inhouse mit Roland Golla, offizieller Cypress Ambassador und seit über 20 Jahren in Testing und Refactoring zu Hause. Auf unserem YouTube Kanal zeigt er in über 70 Live Coding Tutorials, wie Cypress in echten Projekten läuft. Dazu kommt unser Open Source Plugin NCA TESTIFY: Basistests für jede Website, mit einer Zeile im CI/CD Setup. Im Workshop lernt euer Team Setup, stabile Selektoren, Custom Commands und Tests in der Pipeline.
Ein Command braucht einen Namen und eine Funktion. Das klassische erste Beispiel ist ein Helper für data-cy Attribute. Diese Attribute setzt du nur für Tests. Sie ändern sich nicht, wenn jemand CSS Klassen umbaut oder Texte übersetzt.
// cypress/support/commands.js
Cypress.Commands.add('dataCy', (value) => {
return cy.get(`[data-cy=${value}]`)
})
Im Test liest sich das danach so:
it('legt einen Artikel in den Warenkorb', () => {
cy.visit('/produkte')
cy.dataCy('add-to-cart').first().click()
cy.dataCy('cart-count').should('have.text', '1')
})
Über die Option prevSubject legst du fest, wie sich ein Command in eine Kette einfügt:
Zusätzlich kannst du das Subject auf element, document oder window einschränken. Cypress prüft das dann für dich.
In TypeScript kennt der Compiler deinen Command erst, wenn du ihn deklarierst. Dafür erweiterst du das Interface Chainable im globalen Namespace Cypress. Danach bekommst du Autovervollständigung in VS Code oder PhpStorm, und Tippfehler fallen schon vor dem Testlauf auf.
// cypress/support/commands.ts
Cypress.Commands.add('dataCy', (value: string) => {
return cy.get(`[data-cy=${value}]`)
})
declare global {
namespace Cypress {
interface Chainable {
/**
* Holt ein Element über sein data-cy Attribut.
* @example cy.dataCy('add-to-cart')
*/
dataCy(value: string): Chainable<JQuery<HTMLElement>>
login(email: string, password: string): Chainable<void>
}
}
}
export {}
Zwei Details sparen dir Ärger:
{
"compilerOptions": {
"types": ["cypress", "node"]
}
}
Der JSDoc Kommentar ist kein Beiwerk. Er erscheint beim Hovern in der IDE und dient Menschen wie KI Agenten als Kurzdoku direkt am Command.
Fast jede Suite braucht einen Login. Ohne Command steht er in jedem Spec, mit kleinen Abweichungen. Mit cy.session im Command läuft der Login einmal, danach stellt Cypress Cookies, Local Storage und Session Storage aus dem Cache wieder her. Seit Cypress 12 ist cy.session ohne Experiment Flag verfügbar.
Cypress.Commands.add('login', (email, password) => {
cy.session(
[email, password],
() => {
cy.visit('/login')
cy.dataCy('login-email').type(email)
cy.dataCy('login-password').type(password, { log: false })
cy.dataCy('login-submit').click()
cy.url().should('include', '/dashboard')
},
{
validate() {
cy.request('/api/me').its('status').should('eq', 200)
},
cacheAcrossSpecs: true
}
)
})
Was hier passiert:
beforeEach(() => {
// Fake Nutzer aus dem lokalen Seed
cy.login('redaktion@example.test', 'lokales-testpasswort')
cy.visit('/dashboard')
})
Hat deine App einen API Login, geht es noch schneller. Die Cypress Doku rät, die Oberfläche beim Setup so oft wie möglich zu überspringen, etwa mit cy.request. Den Login über das Formular testest du dann genau einmal, in einem eigenen Spec.
Mit Cypress.Commands.overwrite greifst du in einen bestehenden Befehl ein. Du bekommst die Originalfunktion als ersten Parameter und entscheidest, was davor oder danach passiert. Das Beispiel aus der Cypress Doku maskiert sensible Eingaben im Log:
Cypress.Commands.overwrite('type', (originalFn, element, text, options) => {
if (options && options.sensitive) {
options.log = false
Cypress.log({
$el: element,
name: 'type',
message: '*'.repeat(text.length)
})
}
return originalFn(element, text, options)
})
cy.dataCy('login-password').type('lokales-testpasswort', { sensitive: true })
Overwrite ist mächtig und deshalb gefährlich. Wer cy.visit oder cy.click verbiegt, ändert das Verhalten jedes Tests, oft ohne dass es jemand merkt. Unsere Regel: Overwrite nur für Querschnittsthemen wie Logging oder Umgebungen, immer mit Kommentar und immer im Review besprochen.
Nicht jede Wiederholung gehört in einen Command. Die Cypress Doku ist da deutlich: Mach nicht alles zu einem Custom Command. Commands sind für Verhalten gedacht, das du in sehr vielen Tests brauchst. Logik für einen einzelnen Spec bleibt eine normale Funktion.
Page Objects sind die dritte Option. Sie kapseln Selektoren und Abläufe einer Seite in einer Klasse. Das NCA TESTIFY Plugin bringt dafür zum Beispiel eine BasePage Klasse mit. Bei Cypress lohnt sich trotzdem ein kritischer Blick, denn Page Objects zwingen Tests oft durch die Oberfläche, auch wenn ein direkter Weg über cy.request schneller wäre.
Unsere Faustregel in drei Fragen:
| Custom Command | Page Object | Normale Funktion |
|---|---|---|
| Aufruf: cy.login() in der Cypress Kette | Aufruf: loginPage.submit() über eine Klasse | Aufruf: fillAddress() direkt im Spec |
| Gut für: Abläufe, die viele Specs teilen | Gut für: Seiten mit vielen Elementen und Zuständen | Gut für: Logik für einen oder wenige Specs |
| Stärke: global in jedem Spec verfügbar, lesbar wie ein eingebauter Befehl | Stärke: Selektoren einer Seite an einem Ort | Stärke: kein globaler Zustand, leicht zu lesen |
| Risiko: zu viele kleine Commands verstecken, was passiert | Risiko: zusätzlicher Zustand, Tests laufen immer durch die UI | Risiko: Kopien verteilen sich, wenn niemand aufräumt |
| TypeScript: Chainable Interface erweitern | TypeScript: normale Klasse mit Typen | TypeScript: normale Funktionssignatur |
| Für KI Agenten: in AGENTS.md als feste Bausteine nennen | Für KI Agenten: Klassenstruktur erklären | Für KI Agenten: meist ohne extra Kontext verständlich |
Custom Commands entfalten ihren Wert erst, wenn das ganze Team sie nutzt. Dann wird aus einer Sammlung von Helfern ein gemeinsames Vokabular. Ein Frontend Entwickler schreibt seinen ersten E2E Test mit cy.login und cy.dataCy und muss nicht wissen, wie der Login intern funktioniert. So übernehmen Teams Qualität selbst, statt sie an eine einzelne Testperson abzugeben.
Damit das trägt, halten wir uns an die Best Practices der Cypress Doku und ein paar eigene Regeln:
Wird die Sammlung größer, lohnt ein eigenes Paket. Genau so ist das NCA TESTIFY Cypress Plugin entstanden: Commands mit dem Präfix tt wie ttEveryInternalLinkStatusOk oder ttAccessibility, die über npm in jedes Projekt kommen. Ein Import in der Support Datei, und alle Commands sind registriert.
npm install cypress-ncatestify-plugin --save-dev
// cypress/support/e2e.ts
import 'cypress-ncatestify-plugin'
Ein KI Agent, der Cypress Tests schreibt, erfindet ohne Kontext gern seinen eigenen Login, eigene Selektoren und eigene Wartezeiten. Das Ergebnis läuft vielleicht, passt aber nicht zur Suite. Custom Commands lösen das, wenn der Agent sie kennt. Der einfachste Weg führt über deine AGENTS.md.
## Cypress Tests
- Selektoren nur über cy.dataCy('name'), nie über CSS Klassen oder Texte.
- Login immer mit cy.login(email, password). Nie das Formular im Test ausfüllen.
- Keine festen Wartezeiten mit cy.wait(Zahl).
- Neue Custom Commands nur nach Rücksprache. Bestehende Commands nicht ändern.
- Bestehende Specs nicht abschwächen oder löschen. Neue Tests als eigene Datei.
- Testdaten nur aus dem lokalen Faker Seed.
Dazu kommen die TypeScript Typen. Agenten lesen commands.ts und die JSDoc Kommentare und verstehen so Parameter und Zweck jedes Commands. Gute Typen sind damit doppelt wertvoll: für die IDE und für den Agenten.
Der Ablauf bleibt bei NCA immer gleich:
Wie Agenten Tests gegen Anforderungen schreiben, zeigt unser Artikel zu agentischen Akzeptanztests. Wie der Agent danach Testergebnisse aus der Cloud liest, steht bei Cypress Cloud MCP. Und wie OpenCode als Coding Agent arbeitet, erklärt unsere Seite zu OpenCode Features und Plugins.
Ein Hinweis für Teams mit Cypress UI Coverage: Eigene Commands zählen dort erst als Interaktion, wenn du sie in der Konfiguration unter additionalInteractionCommands einträgst.
After adding a custom command, the tests can use it just like any built-in command.
Die beste Command Sammlung ist klein. Wir beraten Teams oft dabei, Commands eher zu streichen als neue zu bauen. Übrig bleiben Login, Selektor Helper, Setup über die API und ein paar fachliche Abläufe, die wirklich überall vorkommen. Alles andere wird wieder zur normalen Funktion. Das macht die Suite lesbarer, für neue Leute im Team genauso wie für KI Agenten.
Bei KI gestützter Entwicklung sind Commands für uns ein Teil der Guardrails für Agentic AI Coding. Sie legen fest, wie getestet wird, so wie ein Schema festlegt, wie Daten aussehen. Mehr dazu findest du in unserem Artikel zu Schema Based AI Coding.
Weiterlesen: wie wir Code Qualität mit KI Agenten sichern, warum Tests für uns lebende Spezifikation sind und wie die KI Weiterbildung für Entwicklerteams Teams beim gemeinsamen Arbeiten mit Agenten unterstützt.
Passend dazu im NCA Cypress Glossar: Testdaten in Cypress für Setup über API und Seeding, Cypress UI Coverage, wo eigene Commands erst nach Konfiguration zählen, und Self Healing Tests als Gegenentwurf zu zentral gepflegten Selektoren.
Optimieren Sie Ihre Webseite mit Astro JS und nutzen Sie die Vorteile einer schnellen, sicheren und barrierefreien Webseite. Erfüllen Sie die gesetzlichen Anforderungen und verbessern Sie die Benutzererfahrung Ihrer Webseite. Mit Astro JS können Sie die Ladezeit reduzieren, die Sicherheit maximieren und die SEO-Optimierung verbessern. Kontaktieren Sie uns, um mehr zu erfahren und um Ihre Webseite auf ein neues Level zu heben.
Die wichtigsten Antworten zu Custom Commands in Cypress: Syntax, TypeScript, Login mit cy.session, overwrite, Page Objects und KI Agenten.
Custom Commands sind eigene Befehle, die du mit Cypress.Commands.add registrierst und danach wie cy.get in jedem Test nutzt. Sie bündeln wiederkehrende Abläufe wie Login, Selektoren oder Setup an einer Stelle. Meist liegen sie in cypress/support/commands.js oder commands.ts. Die Support Datei lädt vor jedem Spec, deshalb sind sie überall verfügbar.
Du erweiterst das Interface Chainable im globalen Namespace Cypress, also mit declare global und namespace Cypress. Dort trägst du jede Signatur ein, etwa dataCy mit Rückgabe Chainable von JQuery. Hat die Datei keinen import oder export, ergänze export {} am Ende. In cypress/tsconfig.json setzt du types auf cypress und node.
Du registrierst einen Command login und rufst darin cy.session mit einer ID, einer Setup Funktion und Optionen auf. Die Setup Funktion meldet sich an, validate prüft eine wiederhergestellte Session. Mit cacheAcrossSpecs teilst du die Session über mehrere Specs im selben Lauf. Seit Cypress 12 brauchst du dafür kein Experiment Flag mehr.
Custom Commands passen für Abläufe, die viele Specs teilen, etwa Login oder Selektor Helper. Page Objects passen für einzelne Seiten mit vielen Elementen und Zuständen. Die Cypress Doku warnt davor, alles zu einem Command zu machen. Logik, die nur ein Spec braucht, bleibt eine normale Funktion. Beides lässt sich sinnvoll kombinieren.
Ja, wenn der Agent sie kennt. Nenn die wichtigsten Commands in deiner AGENTS.md und schreib klare Regeln dazu, etwa nur cy.dataCy für Selektoren und cy.login für die Anmeldung. Typen und JSDoc Kommentare liefern zusätzlichen Kontext. Der Agent schreibt die Tests, ein Mensch reviewt und gibt frei. Bestehende Commands bleiben geschützt.
Mit Cypress.Commands.add legst du einen neuen Befehl an. Mit Cypress.Commands.overwrite änderst du einen vorhandenen, etwa type oder visit. Overwrite bekommt die Originalfunktion als ersten Parameter, damit du das alte Verhalten aufrufen kannst. Weil overwrite jeden Test betrifft, gehört jede Änderung kommentiert und im Review besprochen.
Die Option prevSubject legt fest, wie sich ein Command in eine Kette einfügt. Mit false, dem Standard, startet er eine neue Kette. Mit true ist er ein Child Command und braucht ein vorheriges Subject. Mit optional funktioniert er mit und ohne Subject. Zusätzlich kannst du das Subject auf element, document oder window einschränken.
Weil data-cy Attribute nur für Tests da sind. CSS Klassen ändern sich beim Redesign, Texte bei Übersetzungen, IDs manchmal durch Frameworks. Ein data-cy Attribut bleibt stabil, solange die Funktion gleich bleibt. Ein kleiner Command wie cy.dataCy macht die Nutzung bequem und sorgt dafür, dass alle im Team dieselbe Schreibweise nutzen.
Am einfachsten mit der Option log false bei type, so wie im Login Command. Für eine einheitliche Lösung zeigt die Cypress Doku ein overwrite Beispiel für type mit einer Option sensitive. Dann schreibt Cypress statt des Passworts nur Sternchen ins Log. Nutze in Tests trotzdem nur Fake Zugangsdaten aus deinem lokalen Seed.
So wenige wie möglich. Die Cypress Doku rät von Commands ab, die nur einen einzelnen Befehl umhüllen, etwa cy.clickButton. Lesbarkeit geht vor DRY. Eine kleine Sammlung aus Login, Selektor Helper, Setup über die API und wenigen fachlichen Abläufen trägt in den meisten Projekten weit. Alles andere bleibt normale Funktion.
Ja. Du packst die Commands in ein eigenes Paket und importierst es in der Support Datei. Damit registrieren sich alle Commands automatisch. So funktioniert zum Beispiel das NCA TESTIFY Cypress Plugin, ein Open Source Paket mit Commands wie ttAccessibility. Denk an die TypeScript Deklarationen, damit Nutzer Autovervollständigung bekommen.
Nicht automatisch. UI Coverage wertet standardmäßig nur eingebaute Interaktionsbefehle wie click, type oder check aus. Eigene Commands trägst du in Cypress Cloud im Tab App Quality unter additionalInteractionCommands ein, mit dem Namen ohne das Präfix cy. Nimm dort nur Commands auf, die wirklich mit einem Element arbeiten.