14 min LesezeitFebruar 2026

    Testing mit KI: Warum KI-Code ohne Tests gefährlich ist

    Wie ein einziger undefined-Wert uns lehrte, dass Vertrauen gut ist, aber Testen besser. Mit komplettem Vitest-Setup für React-Projekte.

    Warum KI-generierter Code ohne Tests eine tickende Zeitbombe ist

    *Wie wir durch einen einzigen undefined-Wert gelernt haben, dass Vertrauen gut ist, aber Testen besser.* Tools wie Claude Code, GitHub Copilot oder Cursor revolutionieren die Softwareentwicklung. Features, die früher Tage brauchten, entstehen in Minuten. Komplette CRUD-Systeme, Datenbank-Hooks, UI-Komponenten - alles wird schneller. Aber genau diese Geschwindigkeit hat eine Schattenseite: Wir vertrauen dem generierten Code zu sehr und deployen ihn ohne ausreichende Prüfung. In diesem Artikel zeigen wir anhand eines realen Beispiels aus einem unserer Kundenprojekte, warum automatisierte Tests bei KI-gestützter Entwicklung nicht optional, sondern überlebenswichtig sind.

    Der Bug, der nicht hätte passieren dürfen

    In einem Sponsoring-Management-Tool (React, TypeScript, Firebase) haben wir mit Claude Code ein komplettes Aufgabensystem implementiert: Aufgaben erstellen, Mitarbeitern zuweisen, Fälligkeitsdaten setzen, Status tracken. Der Code sah sauber aus, der TypeScript-Compiler war zufrieden, der Build war grün. Dann hat der Kunde die erste Aufgabe erstellt. Fehler. Die Ursache war fast schon banal: ``typescript // So sah der Code aus await addDoc(tasksRef, { title: values.title, assignedTo: values.assignedTo, dueDate: values.dueDate ? Timestamp.fromDate(values.dueDate) : undefined, relatedEntityType: values.relatedEntityType, // undefined wenn nicht gesetzt relatedEntityId: values.relatedEntityId, // undefined wenn nicht gesetzt createdAt: Timestamp.now(), }); ` Firestore akzeptiert keine undefined-Werte. Punkt. Wenn ein Feld optional ist und der User es nicht ausfüllt, steht dort undefined - und Firestore wirft: "undefined is not a valid Firestore value". TypeScript erkennt das Problem nicht, weil der Typ Timestamp | undefined` technisch korrekt ist. Der Build kompiliert fehlerfrei. Erst zur Laufzeit, wenn ein echter User das Formular abschickt, fliegt alles auseinander.

    Warum KI-Assistenten diesen Fehler immer wieder machen

    Das Muster ist typisch für KI-generierten Code: 1. KI kennt die API-Dokumentation, aber nicht die Runtime-Eigenheiten. Claude weiß, dass Firestore eine NoSQL-Datenbank ist. Aber die spezifische Eigenheit, dass undefined in JavaScript-Objekten bei Firestore zu einem Fehler führt, während null oder das Weglassen des Feldes funktioniert - das ist eine Falle, die in keiner Typdefinition steht. 2. TypeScript gibt falsches Sicherheitsgefühl. Der Code ist typkorrekt. dueDate?: Timestamp erlaubt undefined. TypeScript sagt: alles gut. Aber Firestore sagt zur Laufzeit: nein. 3. Der Happy Path funktioniert immer. Wenn man beim Testen alle Felder ausfüllt, funktioniert alles. Der Bug tritt nur auf, wenn optionale Felder leer bleiben - also genau dann, wenn echte User die App benutzen. 4. KI optimiert für Geschwindigkeit, nicht für Robustheit. Ein KI-Assistent liefert schnell funktionierenden Code. Aber "funktionierend" bedeutet in der Regel: kompiliert und sieht richtig aus. Ohne explizite Anweisung schreibt kein KI-Assistent von sich aus Tests.

    Der Fix ist simpel - aber er hätte automatisch gefunden werden müssen

    Die Lösung ist eine Hilfsfunktion, die undefined-Werte aus Objekten entfernt: ``typescript function stripUndefined>(obj: T): Partial { return Object.fromEntries( Object.entries(obj).filter(([, v]) => v !== undefined) ) as Partial; } // Anwendung const cleanData = stripUndefined(data); await addDoc(tasksRef, { ...cleanData, createdAt: Timestamp.now() }); `` Drei Zeilen Code. Der Bug war in fünf Minuten gefixt. Aber der Kunde hatte bereits einen Fehler gesehen, Vertrauen verloren, und wir mussten erklären, warum eine Basisfunktionalität nicht funktioniert. Das hätte ein einziger Test verhindert.

    Das Testing-Setup: Vitest als Standard

    Für React-Projekte mit Vite ist Vitest die natürliche Wahl. Es nutzt dieselbe Konfiguration wie Vite, ist extrem schnell und bietet eine Jest-kompatible API. Installation: ``bash npm install --save-dev vitest @testing-library/react @testing-library/jest-dom jsdom ` Konfiguration in vite.config.ts: `typescript export default defineConfig({ test: { globals: true, environment: 'jsdom', setupFiles: ['./src/test/setup.ts'], include: ['src/**/*.{test,spec}.{ts,tsx}'], }, }); `` Das gesamte Setup dauert keine zehn Minuten. Danach stehen alle Tools bereit, um den Code abzusichern.

    Was muss getestet werden? Die vier Kategorien

    Nicht jede Zeile Code braucht einen Test. Aber es gibt vier Kategorien, die bei jedem Feature abgedeckt sein müssen: 1. Schema-Validierung (Zod, Yup) Jedes Formular hat ein Validierungsschema. Tests stellen sicher, dass Pflichtfelder erzwungen, Grenzwerte eingehalten und ungültige Werte abgelehnt werden. 2. Utility-Funktionen und Berechnungslogik Reine Funktionen ohne Seiteneffekte sind am einfachsten zu testen. Rabattberechnungen, Datumslogik, Formatierungen. 3. Datenaufbereitung für die Datenbank (der blinde Fleck) Das ist die Kategorie, die fast niemand testet - und wo die meisten Bugs entstehen. Der Code zwischen Formular und Datenbank. ``typescript describe('Firestore-Datenaufbereitung', () => { it('enthält keine undefined-Werte', () => { const taskData = { title: 'Test', dueDate: undefined, // User hat kein Datum gewählt }; const cleanData = stripUndefined(taskData); expect(Object.values(cleanData)).not.toContain(undefined); }); }); `` 4. Zusammenspiel von Formular und Mutation Wird der User-Name korrekt aufgelöst? Wird das Datum richtig konvertiert?

    Die CLAUDE.md als Guardrail für KI-Assistenten

    Wenn KI-Assistenten den Code schreiben, müssen die Regeln dort stehen, wo die KI sie liest. Bei Claude Code ist das die CLAUDE.md im Projektroot. Was gehört rein: ``markdown ## Testing Strategy ### PFLICHT: Tests bei jedem neuen Feature Bevor ein Feature als fertig gilt, MÜSSEN folgende Tests existieren: 1. Zod-Schema-Validierung - Jedes neue Schema testen 2. Utility-Funktionen - Jede reine Logik-Funktion 3. Firestore-Datenaufbereitung - NIEMALS undefined an Firestore 4. Formular-Logik - Transformation von Form-Werten zu DB-Daten ### Bekannte Firestore-Fallstricke Firestore akzeptiert KEIN undefined. Immer stripUndefined() verwenden. `` Der Effekt: Wenn Claude Code das nächste Feature implementiert, liest es diese Regeln und schreibt automatisch Tests dazu. Die KI wird zum eigenen Quality Gate.

    Der Workflow, der funktioniert

    Nach einigen Iterationen hat sich bei uns folgender Workflow etabliert: `` Feature-Anforderung ↓ Implementierung (KI schreibt Code) ↓ Tests schreiben (KI schreibt Tests, weil CLAUDE.md es vorschreibt) ↓ npm run test → Grün? ↓ Ja ↓ Nein npm run build Bug fixen → zurück zu Tests ↓ Erfolgreich? Deploy `` Die Schlüsselstelle: Tests sind kein separater Schritt, der vergessen werden kann. Sie sind Teil der Definition of Done. Konkrete Zahlen aus unserem Projekt: - 39 Tests in drei Dateien, geschrieben in unter 15 Minuten - Laufzeit: unter 2 Sekunden (Vitest ist schnell) - Hätte verhindert: Den undefined-Bug, der den Kunden Vertrauen gekostet hat

    Die fünf wichtigsten Erkenntnisse

    1. TypeScript ist nicht genug. TypeScript prüft Typen zur Compile-Zeit. Aber Runtime-Verhalten (wie Firestores Ablehnung von undefined) wird nicht erkannt. Tests schließen diese Lücke. 2. Der Happy Path ist nicht genug. Wenn alle Felder ausgefüllt sind, funktioniert alles. Die Bugs stecken in den optionalen Feldern, den leeren Eingaben, den Edge Cases. 3. KI braucht klare Regeln. Ohne explizite Anweisung schreibt kein KI-Assistent Tests. Die CLAUDE.md muss klar definieren: Kein Feature ohne Tests. 4. Tests müssen schnell sein. Wenn Tests 30 Sekunden dauern, werden sie übersprungen. Vitest läuft in unter 2 Sekunden. Es gibt keine Ausrede. 5. Testen, was schiefgehen kann, nicht was funktioniert. Der wichtigste Test prüft nicht, ob eine Aufgabe erstellt werden kann. Er prüft, ob undefined-Werte korrekt entfernt werden.

    Fazit: Vertrauen ist gut, Testen ist besser

    KI-Assistenten machen uns produktiver. Aber Produktivität ohne Qualitätssicherung ist wie Autofahren ohne Bremsen: Es geht schnell, bis es knallt. Die gute Nachricht: - Testing-Setup: 10 Minuten - CLAUDE.md-Anpassung: 5 Minuten - Ab dann schreibt die KI die Tests automatisch mit Der ROI: Weniger Bugs in Produktion, weniger peinliche Kundengespräche, mehr Vertrauen in den eigenen Code. Der Bug, der diesen Artikel inspiriert hat, war ein einziger undefined-Wert in einem Firestore-Dokument. Drei Zeilen Fix. Aber er hat uns eine wichtige Lektion gelehrt: Vertraue keinem Code - auch nicht dem eigenen, auch nicht dem KI-generierten - ohne Tests.

    Das war hilfreich?

    Lass uns in 30 Minuten klären, wie KI konkret in deinem Unternehmen helfen kann.