Communitygithub.com

gpanakkal/crucible

Agent-Fähigkeit für TypeScript-Unit-Tests, die fehlschlagen, wenn sie sollten.

Was ist crucible?

Crucible ist eine spezialisierte Fertigkeit für KI-Agenten (wie Claude Code, Cursor, Codex), die sich auf das Schreiben und Überprüfen von TypeScript-Unit-Tests konzentriert. Der Kern der Fertigkeit ist, dass generierte Tests bei fehlerhaftem Produktionscode automatisch fehlschlagen müssen – sie bestehen nur dann, wenn der Code korrekt ist. Damit wird vermieden, dass Tests fälschlicherweise grün werden und Fehler verstecken. Die Fertigkeit unterstützt Projekte, die Vitest, fast-check und Stryker Mutator verwenden. Sie bietet klare Prozesse: Vor der Aktivierung wird geprüft, ob das Projekt per .no-crucible-Datei oder Konfigurationseintrag widersprochen hat. Bei neuen Tests wird zuerst der Ist-Zustand erfasst, dann werden funktionsweise eigenschaftsbasierte Tests (Property-based Testing) mit fast-check geschrieben, die alle Parameter und impliziten Eingaben abdecken. Die Tests werden systematisch auf Branch Coverage und Mutationsscore optimiert. Audits prüfen projektweite oder modulbezogene Testabdeckung und empfehlen Verbesserungen. Die Fertigkeit erstellt detaillierte Debriefs in Markdown, die gefundene Probleme, fehlerhafte Annahmen, Bugs und nicht tötbare Mutanten dokumentieren. Ziel ist eine maximale Branch Coverage und Mutationsscore von 100%, wobei nicht tötbare Mutanten akzeptiert werden, wenn sie nicht vermeidbar sind.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add gpanakkal/crucible

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht crucible?

Wann diese Fertigkeit verwenden

Wenn Sie aufgefordert werden, Unit-Tests in TypeScript-Projekten zu schreiben, zu reparieren oder zu überprüfen.

Wann diese Fertigkeit NICHT verwenden

Beim Schreiben von End-to-End-, Integrations-, UI- oder Simulationstests.

Projektweite Opt-Out-Möglichkeit

Vor der Aktivierung prüfen, ob das Projekt diese Fertigkeit abgelehnt hat. Suchen Sie nach Folgendem:

  • Eine .no-crucible-Datei im Projektstammverzeichnis
  • "crucible: false" irgendwo in AGENTS.md oder .claude/settings.json

Wenn ein Opt-Out-Signal gefunden wird, nicht automatisch aktivieren; wenden Sie diese Fertigkeit nur an, wenn der Benutzer sie in dieser Konversation explizit anfordert.

Regeln

  • Beispielbefehle verwenden pnpm, aber immer den Paketmanager des Projekts verwenden.
  • Keinen Anwendungscode ändern, es sei denn, dies wird ausdrücklich verlangt.
  • Wenn Tests hinzugefügt werden sollen, keine bestehenden Tests ändern.
  • Wenn Tests repariert werden sollen, keine neuen Tests hinzufügen.
  • Wenn Tests überprüft werden sollen, bestehende Tests reparieren und dann nach Bedarf Tests hinzufügen, um die Testkriterien zu erfüllen.

Testkriterien

Unit-Tests sollten:

  • Die maximal mögliche Branch Coverage gemäß Vitest aufweisen.
  • Alle tötbaren Mutanten töten und die maximal mögliche Mutationspunktzahl für den gesamten Code im Geltungsbereich der Aufforderung erreichen (nicht nur für den von Tests abgedeckten Code). Nicht tötbare Mutanten verhindern eine Punktzahl von 100.
  • Möglichst eigenschaftsbasiert sein, es sei denn, es gibt nur eine Handvoll von Eingabefällen. Z. B. hat eine Funktion mit einem einzelnen booleschen Parameter und keinen impliziten Eingaben nur zwei mögliche Eingabefälle, daher lohnt sich keine eigenschaftsbasierte Umsetzung.
  • (falls eigenschaftsbasiert) Arbitrarien haben, die alle möglichen Parameter und impliziten Eingaben abdecken. Es ist entscheidend, dass keine Fälle ausgeschlossen werden, die in der Produktion auftreten könnten. Im Zweifelsfall lieber zu breite Arbitrarien wählen.
  • Fehlschlagen, wenn sie fehlerhaften Code testen oder wenn Arbitrarien absichtlich zu breit gewählt wurden. Betrachten Sie Tests als Anforderungen: Sie sollten entsprechend benannt sein und automatisch bestehen, sobald der Benutzer den Fehler in der Zukunft behoben hat, nachdem der Benutzer die Funktion und/oder Arbitrarien repariert hat. Verwenden Sie nicht test.fails/.skip; dadurch wird dem Benutzer weniger deutlich, dass Aufmerksamkeit erforderlich ist, daher sind Tests, die bestehen, obwohl sie nicht sollten, der höchste zu vermeidende Fehler.

Branch Coverage prüfen und Tests ausführen: pnpm exec vitest run src/foo.test.ts --coverage Nach überlebenden Mutanten im getesteten Code suchen: pnpm exec stryker run --mutate "src/foo.ts"

Testsetup überprüfen

  1. Überprüfen, ob alle folgenden Pakete im Projekt installiert sind: vitest fast-check @stryker-mutator/core @stryker-mutator/vitest-runner @stryker-mutator/typescript-checker
  2. Überprüfen, ob die Vitest- und Stryker-Konfigurationen Dateien korrekt ein- und ausschließen. Stryker sollte keine Dateien prüfen, die nur Testdaten enthalten.
  3. Stryker-Konfiguration überprüfen:
    1. Verwendet den clear-text-Reporter (andere Reporter optional).
    2. Verwendet den TypeScript-Checker und zeigt korrekt auf die TS-Konfigurationsdatei.
  4. Nach anderen Konfigurationsproblemen suchen, die Probleme im Testschreib-Workflow verursachen könnten.
  5. Ergebnisse dem Benutzer melden.

Tests schreiben

Wenn Sie aufgefordert werden, neue Tests zu schreiben, ändern Sie KEINEN ANWENDUNGSCODE ODER BESTEHENDE TESTS.

Zunächst bestehende Tests bewerten, indem Sie Ein Modul bewerten befolgen. Erstellen Sie eine neue Debrief-Datei mit der Vorlage und notieren Sie dort die anfänglichen Coverage- und Mutationswerte.

Zweitens Tests genau nach diesem Prozess schreiben:

Führen Sie Folgendes für jede Funktion/Methode im Modul-Interface durch, wobei Sie eine Funktion beenden, bevor Sie mit der nächsten beginnen:

  1. Bestimmen Sie den Zweck der Funktion, indem Sie Kommentare, ihren Namen, ihre Typsignatur und ihre Verwendung untersuchen. Bei Unsicherheit dies im Debrief vermerken, Tests überspringen und mit der nächsten Funktion fortfahren.
  2. Notieren Sie mögliche Fehler in der Implementierung der Funktion.
  3. Identifizieren Sie auf der Grundlage ihres Zwecks fehlerhafte Annahmen, die die Funktion über ihre Parameter und impliziten Eingaben macht, und notieren Sie Eingabefälle, die wahrscheinlich zu fehlerhaftem Verhalten führen. Z. B. eine Funktion, die eine positive ganze Zahl akzeptiert, aber ihre Eingabe nicht validiert, macht eine fehlerhafte Annahme über ihre Eingabe.
  4. ÄNDERN SIE NIEMALS VORHANDENE TESTS. Wenn Sie Probleme in bestehenden Tests finden, informieren Sie den Benutzer über die gefundenen Probleme.
  5. Schreiben Sie neue Tests wie folgt: a. Erstellen Sie mit fast-check eigenschaftsbasierte Test-Stubs mit Arbitrarien, die alle möglichen Parameter und impliziten Eingaben der Funktion abdecken. Verwenden Sie fc.asyncProperty + await fc.assert(...), wenn die zu testende Funktion asynchron ist. Im Zweifelsfall lieber zu breite Arbitrarien wählen und dies im Debrief erwähnen, damit der Benutzer sie korrigieren kann. Benennen Sie Tests als Beschreibungen des gewünschten Verhaltens. b. Schreiben Sie mit vitest Assertions innerhalb der Stubs, die alle Rückgabewerte und Seiteneffekte wie das Werfen von Ausnahmen, das Mutieren von Eingaben, das Mutieren/Neuzuweisen von Variablen aus äußeren Gültigkeitsbereichen usw. abdecken. Stellen Sie sicher, dass Tests das gewünschte Verhalten bestätigen und die zuvor identifizierten fehlerhaften Annahmen/Fehler abfangen und entsprechend fehlschlagen.
  6. Coverage erneut prüfen: pnpm exec vitest run src/foo.test.ts --coverage
  7. Mutationstest nur für die aktuelle Funktion: pnpm exec stryker run --mutate "src/foo.ts:<startLine>-<endLine>"
  8. Die neu geschriebenen Tests überarbeiten und Schritte 5a und 5b wiederholen, bis die Testkriterien (oben aufgeführt) für die Funktion erfüllt sind.
  9. Den Debrief mit einem Abschnitt zu dieser Funktion aktualisieren.

Nachdem Sie Tests für alle Funktionen geschrieben haben, überprüfen Sie, ob Sie Abschnitte zum Debrief für jede Funktion hinzugefügt haben, und schreiben Sie den Zusammenfassungsabschnitt fertig.

Tests überprüfen

Wenn Sie aufgefordert werden, das gesamte Projekt zu überprüfen, prüfen Sie die projektweite Codeabdeckung und Mutationswerte und empfehlen Sie Bereiche für detailliertere Überprüfungen oder zum Hinzufügen/Aktualisieren von Tests. Bevorzugen Sie Empfehlungen für die wichtigsten und fehleranfälligsten Bereiche der Codebasis – Kern-Geschäftslogik, ereignisgesteuerter Code und komplexe Funktionen.

Wenn Sie aufgefordert werden, einen Teil des Projekts zu überprüfen, suchen Sie nach Modulen oder Funktionen (im Geltungsbereich der Aufforderung), die keine Tests haben, und melden Sie diese dem Benutzer im Post-Audit-Debrief.

Für jedes Modul im Geltungsbereich der Aufforderung, das Tests hat, folgen Sie Ein Modul bewerten. Wenn nach den Bewertungskorrekturen noch Testkriterien nicht erfüllt sind, folgen Sie Tests schreiben, um die verbleibenden Lücken zu füllen.

Ein Modul bewerten

Verwenden Sie diesen Prozess, wenn Sie eine vorhandene Testdatei anhand der Testkriterien bewerten müssen – sowohl vor dem Schreiben neuer Tests als auch bei der Überprüfung.

  1. Codeabdeckung mit Vitest prüfen: pnpm exec vitest run src/foo.test.ts --coverage.
  2. Nach überlebenden Mutanten mit Stryker Mutator suchen: pnpm exec stryker run --mutate "src/foo.ts".
  3. Für jede Funktion im Modul, die Tests hat:
    • Für eigenschaftsbasierte Tests:
      • Nach Eingaben suchen, die die Funktion ohne Ausnahme oder Fehlerwert akzeptieren würde, aber nicht von den Arbitrarien generiert werden können. Arbitrarien nach Bedarf erweitern, um solche Eingaben einzuschließen.
      • Nach Eingaben suchen, die nicht von Arbitrarien abgedeckt werden, insbesondere implizite Eingaben wie Klassenfelder, globale Variablen, Datum/Uhrzeit und zufallsgenerierte Zahlen. Arbitrarien dafür hinzufügen.
    • Fehler in Mock-Implementierungen beheben.
    • Nach Leistungsengpässen suchen.
  4. Die Coverage- und Mutationswerte sowie alle Erkenntnisse im Debrief festhalten.

Test-Debriefs

Formatieren Sie Debriefs gemäß der folgenden Vorlage. Wenn es in einem Funktionsabschnitt nichts zu berichten gibt, schreiben Sie einfach „n/a“. Geben Sie den Debrief in eine Markdown-Datei im Verzeichnis debriefs/ aus.

Debrief: {moduleName/dateiName} {jjjj-mm-tt}

Zusammenfassung

Coverage (Branch) Vorher: X% → Nachher: Y% Zeilen, die nicht abgedeckt werden konnten: {Zeilenbereiche}

Mutationswert (gesamt) Vorher: X% → Nachher: Y%

Probleme

{Aufzählungsliste mit fehlerhaften Annahmen, gefundenen Bugs, Problemen in Tests und fehlschlagenden Tests. Jeder Listeneintrag sollte mit dem projektspezifischen relativen Pfad zur Datei und den Zeilennummern beginnen, an denen das Problem gefunden wurde}

{funktionsname}

Funktionszweck {ein Satz, der beschreibt, was die Funktion tun soll} (Vertrauen: hoch | unsicher) {falls unsicher: was unklar ist und warum}

Gefundene fehlerhafte Annahmen

  • (Zeile {Zeilennummer/-bereich}): {Annahme über Eingabetyp/-bereich/-form, die die Funktion nicht validiert}

In der Implementierung gefundene Fehler

  • (Zeile {Zeilennummer/-bereich}): {Beschreibung + Zeilennummer}

In vorhandenen Tests gefundene Probleme

  • (Zeile {Zeilennummer/-bereich}): {Problembeschreibung + Testname}

Geschriebene Testfälle

  • {kurze Beschreibung jeder getesteten Eigenschaft/Invariante}

Fehlschlagende Tests

  • (Zeile {Zeilennummer/-bereich}): {Testname + Grund}

Nicht tötbare Mutanten

  • (Zeile {Zeilennummer/-bereich}): {kurze Beschreibung}

Verwandte Skills