tdd
Skill20 starsChanged 51 days agoMITView on GitHub
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
194 other projects use a version of this, 66 of them edited.
Adopted by
Most recently taken up by
- ishandutta2007/Awesome-Claude-Skillstheir own version, first seen Nov 8, 2026
- trpc/trpctheir own version, first seen Nov 8, 2026
- wowyuarm/dsh-agent-teamedited, first seen Nov 8, 2026
- Contexera/dsh-agent-teamedited, first seen Nov 8, 2026
- Dimon94/dveritytheir own version, first seen Nov 8, 2026
- Dimon94/skillstheir own version, first seen Nov 8, 2026
Used with
Projects with it also use capture-learning-tools, design-frontend-dev and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
The-Vibe-CompanySkillcapture-learning-tools
Turn technical conversations, bugs, CI failures, review comments,
Also in 5 projects that use this
The-Vibe-CompanySkilldesign-frontend-dev
Clean Impeccable frontend design skill. Use when the user wants to
Also in 5 projects that use this
tristanphvnSkillketchup-video
Catch the user up like /keel:ketchup, with a short silent video of slides for what happened and the waiting calls as text under it. Use for /keel:ketchup-video.
Also in 14 projects that use this
jaydubya818Skillfigure-it-out
Use when novel or multi-phase work needs an auditable workflow and no narrower playbook fits.
Also in 54 projects that use this
jaydubya818Skillprinciple-laziness-protocol
Apply when a refactor is adding wrappers or abstractions instead of simplifying.
Also in 45 projects that use this
- +2 more from The-Vibe-Company
- +5 more from jaydubya818
Other versions194 projects use a version of this.
Word for word · 0
None found.
Edited · 66
- mattpocock/skills★ 309k77% same
- QuivrHQ/quivr★ 40k35% same
- The-Vibe-Company/quivr★ 40k35% same
- MODSetter/SurfSense★ 17k80% same
- GreyDGL/PentestGPT★ 16k14% same
- formbricks/formbricks★ 13k77% same
- ArcReel/ArcReel★ 6.3k77% same
- withcoral/coral★ 4.9k77% same
- bestofjs/bestofjs★ 3.1k78% same
- crbnos/carbon★ 2.8k80% same
56 more not listed
Wrote their own version · 128
- trpc/trpc★ 41ksame name
- Yeachan-Heo/oh-my-claude-sisyphus★ 41ksame name
- Yeachan-Heo/oh-my-claudecode★ 41ksame name
- ccusage/ccusage★ 19ksame name
- ryoppippi/ccusage★ 19ksame name
- open-metadata/OpenMetadata★ 16ksame name
- prowler-cloud/prowler★ 15ksame name
- FastLED/FastLED★ 7.5ksame name
- sanity-io/sanity★ 6.4ksame name
- vinvcn/mattpocock-skills-zh-CN★ 5.5ksame name
118 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository41 other files it gives its agents.
- AGENTS.mdAGENTS.md
- ask-supermattSkill
- babysit-prSkill
- codebase-designSkill
- code-reviewSkill
- commitSkill
- dependency-vettingSkill
- diagnosing-bugsSkill
- domain-modelingSkill
- fix-findingsSkill
- grillingSkill
- grill-meSkill
- grill-with-docsSkill
- handoffSkill
- ideateSkill
- implementSkill
- implement-specSkill
- improve-architectureSkill
- improve-file-structureSkill
- improve-testsSkill
- jurySkill
- orchestrateSkill
- prototypeSkill
- prSkill
- qaSkill
- recover-ciSkill
- refactorSkill
- researchSkill
- resolving-merge-conflictsSkill
- retroSkill
- setup-supermatt-skillsSkill
- ship-prSkill
- teachSkill
- to-questionnaireSkill
- to-specSkill
- to-ticketsSkill
- triageSkill
- wait-whatSkill
- wayfinderSkill
- what-would-you-doSkill
- writing-for-agentsSkill
The file
We split this skill into the rules it gives an agent
4 rules. 0 are common, 3 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 186 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 11
When exploring the codebase, read the glossary (docs/agents/domain.md gives the layout.
- Distinctive: line 19
Before you write a test, name the break it catches: the production change that turns it red.
- Distinctive: line 21
Read tests.md for good and bad test examples before writing the first test, and read mocking.md before adding any mock or test double.
- Distinctive: line 29
Ask: "What's the public interface, and which seams should we test?"
“Common” is measured: kept by at least 6 in 10 of the 186 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Test-Driven Development
TDD is the red → green loop. This skill is the reference that makes that loop produce tests worth keeping: what a good test is, where tests go, the anti-patterns, and the rules of the loop. Every section applies on every cycle: consult them before and during the loop, not after.
When exploring the codebase, read the glossary (docs/agents/domain.md gives the layout; by default GLOSSARY.md at the root, if it exists) so test names and every identifier the change introduces match the project's domain language, and respect ADRs in the area you're touching.
For a bug whose cause is not yet known, load and follow the diagnosing-bugs skill through the host's skill mechanism first: it finds the cause and brings the repro back here as the failing test.
What a good test is
Tests verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't. A good test reads like a specification: "user can checkout with valid cart" tells you exactly what capability exists, and it survives refactors because it doesn't care about internal structure.
Before you write a test, name the break it catches: the production change that turns it red. If you cannot name one, the test observes no behavior yet; find the behavior first.
Read tests.md for good and bad test examples before writing the first test, and read mocking.md before adding any mock or test double. Before any behaviour-preserving change, read characterization.md: it pins code that has no tests, and checks that existing tests cover each change.
Seams: where tests go
A seam is where a module's interface lives (the codebase-design term): tests cross it the way callers do and observe behavior without reaching inside. Tests live at seams, never against internals.
Test only at pre-agreed seams. Before writing any test, write down the seams under test and confirm them with the user. Seams named in the spec or issue you are working from are already confirmed. No test is written at an unconfirmed seam. You can't test everything, so agreeing the seams up front is how testing effort lands on the critical paths and complex logic instead of every edge case. The seams bound the code as well as the tests: when the change needs code behind a seam not on the list (a TUI line when only the Session API is confirmed), confirm that seam before writing the code, so every line the run adds has its red case at a confirmed seam.
Ask: "What's the public interface, and which seams should we test?"
When the shape of that interface is itself in question (how deep the module is, where the seam belongs, what the interface should expose), load and follow the codebase-design skill through the host's skill mechanism for the vocabulary. It is the shared source of the module, interface, depth, seam, adapter, leverage and locality terms, and it is a reference to consult, not a session to run.
Anti-patterns
- Implementation-coupled: mocks internal collaborators, tests private methods, or verifies through a side channel (querying the database instead of using the interface). The tell: the test breaks when you refactor but behavior hasn't changed.
- Tautological: the assertion recomputes the expected value the way the code does (
expect(add(a, b)).toBe(a + b), a snapshot derived by hand the same way, a constant asserted equal to itself), so it passes by construction and can never disagree with the code. Expected values must come from an independent source of truth: a known-good literal, a worked example, the spec. - Change detector: the test goes red only on a deliberate decision (a constant's value, the exact wording of a message, the source text of a script or doc) and stays green through real bugs. Assert the behavior that depends on the decision: "a failing call is tried 5 times, then gives up" in place of
expect(MAX_RETRIES).toBe(5). - Horizontal slicing: writing all tests first, then all implementation. Bulk tests verify imagined behavior: you test the shape of things rather than user-facing behavior, the tests go insensitive to real changes, and you commit to test structure before understanding the implementation. Work in vertical slices instead: one test → one implementation → repeat, each test a tracer bullet that responds to what the last cycle taught you.
Rules of the loop
- Red before green. Write the test first and run it. It is red when the assertion fails for the break you named. An error, a typo, a failed import, a build failure, or a panic is not red yet: fix it and run again. When the test calls a name that does not exist yet, fix it with a stub: add the name so it compiles and returns the zero value (an empty field, a function returning nil or an empty list), then run again until the assertion fails. A test that passes at once pins behavior that already exists. If the code predates this run, rewrite the test to name a break that is not there yet, unless the spec asks for this case over existing behavior: then it is a characterization test, and it counts once you break the code it covers (characterization.md, "When you have enough") and watch it go red. If this run wrote the code ahead of the test, the test counts only once you break that code (the mutation check below) and watch it go red: do that before counting the cycle, then undo the break. Then write only enough code to pass it: every branch you add is one the failing case runs. A behavior the case does not reach (another input form, another case of the same rule, a later slice's rule) waits for its own red test, even when the natural implementation would cover it in the same edit. Don't anticipate future tests or add speculative features.
- Green is the affected seam. During a cycle, run the new test and the tests for the affected seam, plus lint on changed files and the narrowest supported typecheck. Use the full command when the runner cannot select that scope or shared configuration makes the effect project-wide. Before a completed behavior is committed or handed off, run the repository's full required gate, including its full suite. A cycle is not a commit boundary: several cycles can complete one behavior. Reuse a passing check only while its relevant files, dependencies, configuration, and environment are unchanged; a later phase or commit alone does not invalidate it. Repository rules and hooks still apply. Report every failure by name, including failures you did not cause.
- One slice at a time. One seam, one case, one minimal implementation per cycle. A case is one input and the assertions on it, whatever file holds it: in a table-driven test or a script of many cases, add one case per cycle and watch that case go red, since a runner that stops at its first failure shows only the first new case red and hides the rest.
- Mutate before you finish. Break every file this run changed in small, realistic ways, one at a time: a wrong constant or argument, the wrong branch, a missing side effect, an empty return, a missing check for empty, zero, null, or bad input. Run the tests for that seam, then undo the change. Each mutation must turn at least one test red as the red rule above defines it, an assertion failing for that break: a mutation that only panics or fails to compile proves nothing, so pick another. Change the logic and leave every import and variable in use (
false && condin place of a deletedcond,x += 0in place ofx = x): a compiler that rejects unused names, as Go's does, or a vet step that rejects self-assignment, reports the mutationbroken. One that stays green marks behavior no test protects: add the test that turns it red, or, when no input reaches the mutated code or the mutation changes no observable result (an equivalent mutation), delete that code, since the red rule admits no branch a failing case does not run. An equivalent mutation of code that has to stay (a==that no input tells apart from>=, a value the output never shows) is a survivor: write down the input you tried to tell the two apart and why none can, and list it by name in your report. Rewriting the code so the mutation no longer applies is a behaviour change: it needs its own red case, and the rewritten code is mutated again. The check is done when every mutation is red or is a listed survivor. The mutation runner requires a POSIX shell, Perl, and standard Unix utilities (cat,cp,date,head,mktemp, andrm). Run them withsh <this skill's directory>/scripts/mutate.sh [-b BUILD] [-t SECONDS] TEST MUTATION...(scripts/mutate.sh, bundled with this skill). Each MUTATION is a file: the target path on line 1, then the exact text to find, a line holding only====, then the replacement. A missing separator is rejected asmissing; bytes outside the replacement, including the final newline, are preserved. Write them into amktemp -ddirectory, one heredoc per file. Call it throughsh, because an installed copy can lose its execute bit. A batch runs BUILD and TEST once per mutation, so a batch of dozens can outlast your shell tool's time limit: run a large batch in the background and read its output when it exits; until then leave the working tree alone, since the batch rewrites each target in place and restores it from a copy, so an edit made meanwhile is lost or skews the results. A mutation that removes a loop or recursion guard can run TEST forever. An explicit-t SECONDSalso bounds the unchanged baseline;-t 0disables TEST timeouts. Without an explicit limit, mutation tests get five times the unchanged run plus a minute. A timeout kills TEST and processes still in its process group. Test commands that detach descendants into another group or session must clean them up themselves. Count atimeouton such a guard as red, since never ending is the break it names. It applies each one alone, restores the file, and reports ittest-failed,GREEN,timeout(TEST ran past the limit),broken(the-bbuild step failed) ormissing(its text was not found). A failed backup stops before that mutation. A failed restore exits 2 and retains the backup at the path printed on stderr; recover it before continuing. Failed TEST output is printed on stderr with the mutation name. Inspect that output before countingtest-failedas red: identify the assertion and confirm it failed for the intended break. Missing diagnostics require rerunning with a test command that exposes them. A runtime error or failed import is not red. Exit 0 means every TEST failed; it does not certify the failure causes. It first runs BUILD and TEST on the unchanged code and stops with exit 2, printing the failing command's output, when either fails, since every mutation would then read red: fix TEST until it passes there (TEST runs throughsh, so quote a|in a-run A|Bpattern). - Refactoring is not part of the loop. It comes after the slice is green, usually on what review found (the
code-reviewskill), with the tests left unchanged apart from a mechanical rename or move. A refactor runs no red-green cycle: the seam's existing tests are its characterization tests. Each step runs the affected checks and characterization.md's break check; the completed refactor runs the full required gate before commit or handoff.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

