CommunityCodierung & Entwicklunggithub.com

ShortArrow/test-design

Leitet Testfälle ab, ausgelöst durch Momente, die schwache hervorbringen: eine Testliste schreiben, die den Happy Path nur umschreibt; Tests aus der Implementierung ableiten; die vom Lastenheft benannte Grenze testen, die andere aber übersehen; die Rollen aus dem Lastenheft aufzählen, die aufgerufene Instanz aber vergessen; eine Bedingung nach der anderen vom Happy Path variieren; eine Zustands- oder Entscheidungstabelle zeichnen, ohne jede Zeile mit einem Test zu verknüpfen; ein erwartetes Ergebnis mit „oder“ enthalten; Fehlerpfade als unwahrscheinlich überspringen; einen Pfad weder implementieren noch testen; oder eine Suite nur durch Lesen als ausreichend bewerten. Ein aus der Implementierung abgeleiteter Test besteht per Konstruktion; die Abdeckung zählt Klassen, nicht Tests. Verwenden Sie dieses Skill beim Erstellen eines Testplans oder einer Testliste, wenn ein Anwendungsfall das Lastenheft in der Hand ist, beim Hinzufügen von Tests zu bestehendem Code, beim Überprüfen einer Suite auf Lücken, und wenn eine Suite komplett grün ist, aber wenig beweist.

Was ist test-design?

Dieses Skill, `test-design`, hilft Entwicklern und KI-Agenten, Testfälle aus Spezifikationen abzuleiten, anstatt aus der Implementierung. Es adressiert häufige Fallstricke, die zu schwacher Testabdeckung führen: nur den Happy Path testen, Randbedingungen nur einseitig prüfen, Fehlerpfade auslassen, oder Tests aus dem Code selbst generieren. Der Kernansatz ist, die Spezifikation systematisch anzugreifen: Äquivalenzklassen bilden (auch ungültige), Randwertanalyse für beide Enden eines Bereichs durchführen, Entscheidungstabellen für kombinierte Bedingungen nutzen, Zustandsübergänge inklusive verbotener testen, und Fehlerpfade als eigene Klassen behandeln. Das Skill unterstützt Plattformen wie Claude Code, Cursor und andere KI-Entwicklungsumgebungen, die System-Prompt- oder Agent-Konfigurationen erlauben. Die Methode zählt nicht die Anzahl der Tests, sondern die Abdeckung der Spezifikationsklassen: Jede Klasse sollte genau einen Test haben, und die Abdeckung sollte mit einem klaren Kriterium (z.B. Each Choice, MC/DC) gemessen werden. Es enthält auch spezifische Regeln, um fehlende Entscheidungen oder nicht implementierte Pfade explizit zu machen, sodass Lücken sichtbar bleiben und nicht in Kommentaren vergraben werden.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ShortArrow/skills/tree/HEAD/skills/test-design

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

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

Dokumentation

Testdesign

Die Fälle entscheiden, was die Suite abfangen kann. Alles danach — die Testumgebung, der Runner, die Zählung — führt diese Entscheidung nur aus.

Die Momente, die dieses Skill ersetzt

Kurz vor …Stattdessen …
den Happy Path schreiben und aufhörenden Eingaberaum durchgehen: für jeden Parameter seine Klassen und seine Grenzen
Fälle aus der Implementierung ableitensie aus der Spezifikation ableiten, und die Implementierung überraschen lassen
mit einem komfortablen Wert testenden letzten Wert innerhalb und den ersten Wert außerhalb jeder Grenze testen
die Grenze testen, die die Spezifikation nenntjeder Bereich hat zwei Enden; das im Satz nicht genannte ist immer noch eine Grenze
die Rollen aufzählen, die die Spezifikation auflistetden Aufrufer hinzufügen, den sie vergessen hat: keine Rolle, nicht authentifiziert, nicht zugewiesen
eine Bedingung ausgehend vom Happy Path variierendie Entscheidungstabelle erstellen und die Regeln abdecken, bei denen zwei Bedingungen gleichzeitig fehlschlagen
eine Zustandstabelle zeichnen und weitermachenin jede Zeile eine Test-ID setzen; am meisten in die Zeile, die „nicht erlaubt“ sagt
„abgelehnt, oder akzeptiert sofern …“ als erwartetes Ergebnis schreibenein Ergebnis pro Fall; eine Spezifikation, die sich nicht entscheiden kann, ist eine offene Frage, kein Test
Fehlerpfade als unwahrscheinlich überspringenjeder Fehlermodus ist eine Klasse: ungültige Eingabe, fehlende Ressource, verweigert, Zeitüberschreitung, halb fertig
einen Pfad ohne Test, mit einem Überspring-Marker oder einem unbehaupteten Platzhalter unimplementiert lasseneinen Test schreiben, dass der Pfad heute als unimplementiert zurückgewiesen wird; er besteht jetzt und wird rot an dem Tag, an dem ihn jemand baut (weiter unten)
eine Funktion nach ihrem Hauptablauf testendie alternativen und Ausnahmeabläufe aus dem Anwendungsfall ablesen; jeder ist eine Klasse
eine Suite durch Lesen bewertensie gegen die Spezifikation zählen: Klassen, beide Grenzen, Regeln, Übergänge
einen fünften Test zu einer abgedeckten Klasse hinzufügenihn für eine nicht abgedeckte Klasse ausgeben — der fünfte kostet Laufzeit und bringt keine neue Abdeckung

Die Spezifikation angreifen, nicht die Implementierung

Ein Test, der durch Lesen des Codes geschrieben wurde, behauptet, was der Code tut. Er besteht bei Ankunft, kodiert die aktuellen Fehler als Erwartungen, und sein Fehlschlagen nach einer Änderung sagt „der Code hat sich geändert“, was bereits bekannt war. Dies ist gemessen, nicht vermutet: bei 24 Java-Repositories neigten LLM-generierte Orakel dazu, das tatsächliche Verhalten des Programms einzufangen und nicht sein erwartetes Verhalten (Konstantinou, Degiovanni, Papadakis, arXiv:2410.21136).

Leiten Sie aus dem ab, was die Sache tun soll — der Spezifikation, dem Drahtformat, dem Vertrag — und führen Sie es erst dann aus. Die eine legitime Ausnahme ist der Charakterisierungstest, der bewusst das aktuelle Verhalten festhält, und er ist als solcher markiert, damit niemand später einen festgehaltenen Fehler mit einer Anforderung verwechselt.

Ein nützlicher Hinweis: Wenn jeder Test beim ersten Lauf grün war, wurde die Suite aus der Implementierung abgeleitet, unabhängig von der Absicht.

Äquivalenzklassen: Klassen zählen, nicht Tests

Eingaben, die der Code nicht unterscheiden kann, bilden eine Klasse, und ein Test pro Klasse ist ausreichend — der zweite bis fünfte kostet Laufzeit und beweist nichts Neues. Die Disziplin wirkt in beide Richtungen: keine Klasse ungedeckt, keine Klasse versehentlich doppelt abgedeckt.

Eine Suite mit siebzehn Tests wirkt gründlich. Ob sie es ist, hängt davon ab, in wie viele Klassen diese siebzehn fallen, und diese Zahl erscheint in der Ausgabe keines Runners. Sie muss von Hand gegen den Eingaberaum gezählt werden — was ein Testplan ist.

Die Klassen, die die Spezifikation auflistet, sind die einfache Hälfte. Eine Rollentabelle mit drei Zeilen hat eine vierte Klasse, die Anfrage, die zu keiner davon passt, und es ist die, die eine aus der Tabelle gebaute Suite nie enthält. Schreiben Sie für jeden Parameter die ungültigen Klassen neben die gültigen, bevor Sie einen Fall schreiben: falscher Typ, fehlend, außerhalb jedes aufgeführten Werts, der Aufrufer ohne jegliche Rechte.

Der Lehrplan formuliert dies als Regel und nicht als Gewohnheit: Bei der Äquivalenzklassenbildung sind die Abdeckungselemente die Partitionen, 100 % bedeutet jede identifizierte Partition getestet „einschließlich ungültiger Partitionen“, und die Partitionen „dürfen sich nicht überlappen und müssen nicht-leere Mengen sein“ (ISTQB CTFL v4.0.1 §4.2.1). Mit mehreren Parametern nennt es das schwächste Kriterium Each Choice — jede Partition jedes Parameters einmal, Kombinationen ignoriert — was das Niveau ist, das die meisten Suiten erreichen, ohne seinen Namen zu kennen, und wo unten die Entscheidungstabelle beginnt.

Grenzen, denn dort liegen die Fehler

Um-eins-Versatz ist der häufigste arithmetische Fehler, und er ist überall außer am Rand unsichtbar. Das Paar, das an jeder Grenze zählt, ist der Grenzwert und sein nächster Nachbar über der Linie, was die 2-Wert-Grenzwertanalyse ist (CTFL v4.0.1 §4.2.2); die 3-Wert-Analyse fügt auch den Nachbarn auf der Innenseite hinzu, und der Lehrplan zeigt, was das bringt: eine Prüfung als x ≤ 10 gedacht, aber als x = 10 geschrieben, besteht sowohl bei 10 als auch bei 11, und nur 9 fängt es. Die wiederkehrenden Ränder: leer, genau eins, viele; null und negativ; das deklarierte Maximum und eins darüber; der Wert, der genau der Puffer, das Limit, die Zeitüberschreitung ist.

Ein konkretes Paar von dieser Maschine: eine PATH-Prüfung, die bei 8.190 Zeichen in Ordnung ist und bei 8.192 fehlschlagen muss, muss bei diesen beiden Werten getestet werden. Ein Bestehen bei 4.000 und 12.000 sagt fast nichts über die Grenze dazwischen aus.

Wo die Grenze eine formulierte Vorbedingung ist, ist der Wert darüber ein Fehler des Aufrufers und kein Fall mit einem erwarteten Ergebnis; design-by-contract entscheidet, welche der beiden eine bestimmte Kante ist, und der Test behauptet dann die zutreffende.

Die Seite, die die Spezifikation nicht nannte

„Bis zu 10 MB“ nennt ein Ende eines Bereichs. Das andere Ende existiert, ob der Satz es erwähnt oder nicht, und die aus dem Text abgeleiteten Fälle hören dort auf, wo der Text aufhört: eine Suite mit der Obergrenze getestet bei −1, 0 und +1 Bytes und nichts unter 1.024 hat eine Grenzwertanalyse auf einer Hälfte des Bereichs durchgeführt. Die Definition hat keine Seite: „die minimalen und maximalen Werte einer Partition sind ihre Grenzwerte“ (CTFL v4.0.1 §4.2.2). Schreiben Sie beide für jede Partition zuerst auf, dann nehmen Sie jeden mit seinem nächsten Nachbarn in der benachbarten Partition. Die unbenannte Seite ist normalerweise null, leer oder eins, und die Spezifikation schweigt normalerweise dazu, weil niemand entschieden hat.

Zwei Bedingungen gleichzeitig bewegen

Eine Suite, die durch Ändern einer Bedingung vom Happy Path aufgebaut wird, deckt jeden Wert jeder Bedingung und fast keine ihrer Kombinationen ab: Format falsch, Größe über, Anzahl über, jede allein, und kein Fall, bei dem zwei zusammen fehlschlagen. Welcher Fehler gewinnt, wenn beide zutreffen, steht selten in der Spezifikation, also verbirgt der fehlende Fall eine fehlende Entscheidung.

Legen Sie die Bedingungen als Entscheidungstabelle aus und zählen Sie die Regeln, dann decken Sie die Regeln ab, bei denen zwei Bedingungen gleichzeitig fehlschlagen, und die Regel, bei der eine Rollenbeschränkung und eine Formateinschränkung beide zutreffen. Beim Testen mit Entscheidungstabellen sind die Abdeckungselemente die Spalten mit realisierbaren Kombinationen, und 100 % bedeutet jede solche Spalte getestet (CTFL v4.0.1 §4.2.3); der Lehrplan fügt hinzu, dass die Tabelle „hilft, Lücken oder Widersprüche in den Anforderungen zu finden“, was die oben genannte fehlende Entscheidung ist, die von selbst auftaucht. Dasselbe Dokument kann als vollständig abgedeckt unter Each Choice und zu einem Viertel abgedeckt unter den Spalten gelesen werden, und nur die zweite Zahl sagt etwas über die Kombinationen aus. Wenn die Regelzahl das Produkt einer Menge von Flags ist, ist die günstigere Lösung upstream: state-first fasst die Flags in die Zustände zusammen, die auftreten können, und die Tabelle schrumpft auf diese.

Eine Tabelle ist eine Behauptung über die Suite

Eine Zustandstabelle, eine Entscheidungstabelle, die Ablaufliste eines Anwendungsfalls: jede Zeile behauptet, dass ein Test für sie existiert. Setzen Sie die Test-ID in die Zeile. Eine Zeile ohne ID ist eine nicht abgedeckte Klasse, und die Zeile, die „nicht erlaubt“ lautet, ist diejenige, die am wahrscheinlichsten leer ist, weil das Schreiben des Verbots sich wie eine Behandlung anfühlte. Der verbotene Übergang — das zweite Senden, während eines in Bearbeitung ist — ist der Test, und die Wächterfunktion, die ihn stoppen soll, ist das zu testende Objekt.

Die Zustandstabelle macht diese Zeile explizit: ein ungültiger Übergang ist eine leere Zelle, und das stärkste der drei Kriterien, die der Lehrplan definiert, alle Übergänge abgedeckt, erfordert das Ausführen jedes einzelnen — ein Test pro Testfall, so dass ein Defekt keinen anderen maskieren kann (CTFL v4.0.1 §4.2.4). Abdeckung gültiger Übergänge, der 0-Wechsel, bei dem die meisten Suiten aufhören, berührt diese Zellen nie, weshalb eine ungetestete „nicht erlaubt“-Zeile grün bleibt.

Lesen Sie dann die beiden Dokumente gegeneinander. Ein Test, dessen Pfad nicht mit der Tabelle übereinstimmt (die Tabelle sagt fehlgeschlagen → sendet, der Test geht fehlgeschlagen → ausgewählt → sendet), bedeutet, dass eines von beiden falsch ist, und nichts außer dem Vergleich findet heraus, welches. Selbstübergänge und die Übergänge aus dem Fehlerzustand zählen ebenfalls als Zeilen.

Ein Ergebnis pro Fall

„Abgelehnt, oder falls akzeptiert, keine beschädigten Daten nach dem Senden“ kann nicht bestanden oder fehlschlagen. Es erscheint ehrlich, wenn die Spezifikation nie gesagt hat, was mit einer Datei von null Bytes passiert und der Autor es abgelehnt hat, sich eine Antwort auszudenken, und es überlebt die Überprüfung, weil der Fall sichtbar vorhanden ist. Die Disjunktion versteckt sich in der erwarteten Spalte. Die korrekte Form ist eine Frage an den Eigentümer der Spezifikation, als solche aufgeführt, und kein Test für diese Klasse, bis sie beantwortet ist.

Fehlerpfade sind auch Klassen

Die unglücklichen Pfade sind die, wo sich ungetesteter Code ansammelt, weil nichts sie im normalen Gebrauch ausübt — ein Sperreninhaber, der mitten im Lauf stirbt, ein zugeordneter Ordner, der nicht existiert, Eingabe mit dem erwarteten fehlenden Feld. Jedes ist eine Äquivalenzklasse mit dem gleichen Anspruch auf einen Test wie jeder Eingabebereich. Eine Suite, die nur beweist, dass das Werkzeug funktioniert, wenn alles kooperiert, hat die Demo getestet, nicht das Werkzeug.

Anwendungsfälle zählen die Klassen vor dem Code auf

Ein Anwendungsfall ist eine bereits in Klassen geschnittene Spezifikation: ein Hauptablauf, jeder alternative Ablauf, jeder Ausnahmeablauf, und die Vorbedingung, unter der jeder betreten werden kann. Wer ihn schrieb, hat die Aufzählung durchgeführt, die dieses Skill verlangt — die alternativen und Ausnahmeabläufe sind die Fehlerpfade — also hat eine Suite, die den Hauptablauf ausübt, eine Klasse von den N abgedeckt, die das Dokument auflistet.

Lesen Sie die Abläufe aus dem Anwendungsfall ab und geben Sie jedem seinen Test, dann überprüfen Sie die Vorbedingungen, denn ein Ablauf ist nur dann erreichbar, wenn seine Vorbedingung gelten kann. Ein Paritätscheck für übersetzte Seiten hat einen Hauptablauf (beide Sprachen bearbeitet und übertragen), einen alternativen Ablauf (eine einseitige Bearbeitung als Ausnahme deklariert), und zwei Ausnahmeabläufe, die erst auftauchen, wenn die Vorbedingungen aufgeschrieben sind: der Baum ist schmutzig, also kann die Veralterung noch nicht beurteilt werden; die Historie wurde umgeschrieben, also ist ein deklarierter Commit nicht mehr auflösbar. Beide traten innerhalb einer Woche auf einer Site auf. Der Happy Path allein hätte keinen von beiden gezeigt.

Ob ein Ausnahmeablauf tatsächlich auftreten kann, wird nicht dadurch entschieden, wie unwahrscheinlich er sich anfühlt. Das Betriebsfenster sagt, was außerhalb des Rahmens liegt, und die Gefahrenanalyse sagt, was bleibt; beide leben in assurance-case, und dieses Skill akzeptiert die Liste, die sie produzieren, anstatt sie nach Intuition zu beschneiden.

Abdeckung ist eine Zahl unter einem benannten Kriterium

Ein Testdokument drei Wege gemessen: 100 % der Bedingungen, 90,9 % MC/DC, 25 % der Entscheidungsregeln. Alle drei sind vom selben Datensatz wahr, also sagt eine Abdeckungszahl ohne ihr Kriterium nichts, und eine Zahl, deren Kriterium nach der Zählung gewählt wird, sagt noch weniger. Nennen Sie es vor dem Zählen, in den eigenen Begriffen des Lehrplans, damit die Zahl überprüft werden kann: Partitionsabdeckung und Each Choice (§4.2.1), 2-Wert- oder 3-Wert-Grenzwertanalyse (§4.2.2), Entscheidungstabellen-Spalten (§4.2.3), Alle Zustände, Gültige Übergänge oder Alle Übergänge (§4.2.4). MC/DC ist nicht im Grundlagenlehrplan; es stammt aus den Sicherheitsstandards (DO-178C, ISO 26262), und es neben den anderen aufzuführen, ohne das zu sagen, ist die Art von gemischter Zitierung, die als Strenge gelesen wird. Der Rest dessen, was eine Zahl ihrem Leser schuldet, steht in measured-claims.

Eine Suite überprüfen: zählen, nicht urteilen

Die Frage, ob eine Suite angemessen ist, gibt die blinden Flecken zurück, die sie produziert hat. Eine zweite Sitzung mit demselben Modell teilt sie, und dasselbe eine Person einen Tag später. Der Lehrplan nennt das „etwas Unabhängigkeit“, die zweite seiner vier Stufen, und sagt, wo der Wert herkommt: „Unterschiede zwischen den kognitiven Verzerrungen des Autors und des Testers“ (CTFL v4.0.1 §1.5.3). Eine zweite Sitzung mit demselben Modell teilt die Verzerrungen und behält nur das Etikett. Der Schritt, der sie nicht teilt, ist das Zählen: Listen Sie die Klassen aus der Spezifikation auf und haken Sie die mit einem Test ab, listen Sie beide Grenzen jedes Bereichs auf, listen Sie die Regeln der Entscheidungstabelle auf, listen Sie die Zeilen jeder Zustandstabelle auf, und zitieren Sie die Datei und die Zeile jeder Lücke. Ob ein erwarteter Wert richtig ist, bleibt ein Urteil und bleibt bei einem Leser, der ihn nicht geschrieben hat; ob eine Klasse einen Test hat, ist Arithmetik. Wenn die Zählung eine Stichprobe und nicht erschöpfend war, sagt der Bericht "Stichprobe". Die Form der Widerlegung durch Voreinstellung für das Urteil steht in adversarial-verify; dieses Skill liefert, was zu zählen ist.

Wenn die Anfrage eine Klasse entfernt

„Das doppelte Senden kann nicht passieren, weil der Button deaktiviert ist, streichen Sie diese Zeile“ entfernt eine Klasse aus der Suite mit der Stärke einer Wächterfunktion in einer Schicht. Tun Sie, was gefragt wurde, und sagen Sie in einem Satz, welche Klasse jetzt ungedeckt ist und was sie erreichen würde: die Zustandsmaschine akzeptiert immer noch ein zweites Senden von jedem Aufrufer, der nicht der Button ist. Eine mit diesem Satz gelöschte Zeile ist eine Entscheidung; eine ohne diesen Satz gelöschte Zeile ist eine Lücke, die niemand wiederfinden wird.

Ein unimplementierter Pfad hat einen Test, der das sagt

Ein absichtlich aus dieser Änderung ausgelassener Pfad, eine Rolle, die diese Version nicht unterstützt, ein noch nicht verarbeitetes Format, ein Branch, der NotImplementedException wirft oder todo!() aufruft, ist immer noch eine Klasse der Eingabe, und die Suite zeichnet auf, was dort heute passiert. Schreiben Sie den Test, dass der Pfad als unimplementiert zurückgewiesen wird: die Ausnahme oder den Fehlerwert, den er auslöst, das fehlende Menüelement, die Antwort, die „nicht unterstützt“ lautet.

Dieser Test besteht jetzt und erledigt zwei Aufgaben. Er setzt die Lücke in die Liste der Suite, wo ein Leser, der Klassen zählt, sie findet, anstatt in einem Kommentar oder einem Ticket. Und er wird rot an dem Tag, an dem jemand den Pfad implementiert, was der Moment ist, in dem seine echten Fälle geschrieben werden müssen; der fehlschlagende Test ist die Erinnerung, und er wird ersetzt, nicht gelöscht.

Ein Überspring-Marker oder ein ausstehender Test ist kein solcher Test. Ein ausstehender Test ist eine Leerstelle, die nicht rot werden kann; der Ersatz für ihn ist der echte Test, sobald er geschrieben ist.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

ShortArrow/interface-design

Deciding how a screen looks and behaves, triggered by the moments that hand the decision to the user unworked: about to ask which layout, which colour, which placement, how to draw a diagram, how wide a pane, how to split a view; about to call a visual choice a matter of taste; about to treat "it looks fine" as having checked it; about to ship a control sized by eye; about to read an automated accessibility pass, or a Lighthouse score of 100, as a clean bill of health. Most of these have an answer in a published standard, a measurable threshold, or one screenshot — WCAG 2.2 fixes contrast, target size, reflow and focus; a design system fixes spacing and components; axe-core finds about 57% of WCAG issues, and Lighthouse's accessibility score is that same engine weighted, so both leave the rest to a person. What survives is a genuine question, asked with the evidence attached. Use before asking any question about appearance, layout or interaction, and before calling

ShortArrow/library-design

Designing a library — a published package, or an in-app module from the moment it has a second consumer. The implementation stays editable forever, while the public API, the dependency set, the performance characteristics and every observable behaviour freeze at first external use (Hyrum's law). Five duties to the caller: take no control, add no hidden cost (zero-cost abstraction as the bar), hold no hidden state, hide no failure, block no escape. Use when designing or reviewing a public API, when extracting shared code into a module, when asked to "make this reusable", when a signature-compatible change alters an observable behaviour, and when an application is being shaped around a framework's types and lifecycle.

Verwandte Skills