Tdd
My personal collection of AI skills
npx -y skills add abijith-suresh/skills --skill tddAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Builds features test-first using red-green-refactor. Use only when the user explicitly invokes the tdd skill. Do not trigger from ordinary requests to add tests or implement a feature.
SKILL.md
4.4 KB, as published. Nobody here has run it
TDD
One test. Minimal code. Never the other way around.
What makes a good test
Tests verify behavior through public interfaces. They describe what the system does, not how. A good test survives a complete internal refactor — if you rename a private method or restructure an implementation and a test breaks, that test was testing implementation, not behavior.
Bad signals:
- Mocks internal collaborators or private methods
- Breaks on rename with no behavior change
- Verifies internal state instead of observable output
Good signals:
- Reads like a spec: "user can checkout with a valid cart"
- Exercises a real code path end-to-end
- Survives refactors
The anti-pattern: horizontal slicing
Never write all tests first and then all implementations.
WRONG — horizontal:
RED: test1 test2 test3 test4
GREEN: impl1 impl2 impl3 impl4
RIGHT — vertical tracer bullets:
RED → GREEN: test1 → impl1
RED → GREEN: test2 → impl2
RED → GREEN: test3 → impl3
Horizontal slicing produces tests that reflect imagined behavior written before you understood the implementation. They test shape, not behavior.
Workflow
1. Plan the interface
Before writing any test, confirm with the user:
- What is the public interface? (method signatures, API endpoints, whatever callers use)
- Which behaviors matter most? Prioritize — you cannot test everything.
Design for testability. A small interface hiding a lot of behavior is easier to test than a sprawling one.
2. Tracer bullet
Write ONE test for the most important behavior. The simplest end-to-end path that proves the design works.
RED: Write the test. Run it. Confirm it fails for the right reason — not a missing import, but because the behavior doesn't exist yet.
GREEN: Write the minimum code to pass. Nothing more.
3. Incremental loop
For each remaining behavior:
RED: Write the next test. Confirm it fails. GREEN: Write minimum code to pass. Confirm it passes.
One test at a time. Never write the next test until the current one is green. If the next test passes without new code, the behavior was already covered — note it and move on.
4. Refactor
Once all tests are green:
- Remove duplication
- Improve names
- Simplify interfaces where possible
Run the full test suite after every refactor step. Never refactor while RED.
Test pyramid
Invest testing effort according to the pyramid — most tests should be small and fast, with progressively fewer at each higher level:
- Small (unit): pure logic, no I/O, no network, milliseconds each — the majority
- Medium (integration): crosses a boundary (database, API, file system, external service)
- Large (end-to-end): critical user flows only — keep these few
A suite of slow end-to-end tests is expensive to run and expensive to maintain. Push coverage down to the smallest layer where it makes sense.
What to test at each layer
Small tests: pure functions, domain rules, validation logic, data transforms. No infrastructure involved. The fastest feedback loop.
Medium tests: behavior that crosses a layer boundary — a method that reads from real storage, an endpoint that writes to a real database. Use real infrastructure where practical. Avoid mocking what you own.
Large tests: flows a real user would run end-to-end. Reserve for the most critical paths. Lower-layer tests should cover everything else.
Using mocks and fakes
Prefer real implementations over test doubles. The more your tests use real code, the more confidence they provide.
Use a mock or fake only when the real dependency is:
- Too slow (external network call, heavy process)
- Non-deterministic (time, randomness)
- Has side effects you cannot control (email sending, payment processing)
Never mock what you own. If you own the code, test it. Mocking internals creates tests that pass while production breaks.
Checklist per cycle
- Test describes behavior, not implementation
- Test uses public interface only
- Test would survive an internal refactor
- RED confirmed: test fails for the right reason
- GREEN: code is the minimum needed to pass this test
- No speculative code added
- Refactor complete: no duplication, clear names, full suite still green
Gives 2 of the 12 instructions most tdd skills give
Counted across 439 of the 443 authors here whose files we hold, read 2026-08-06
- write minimal code to pass the testhere, and in 302 of 439, across 218 files
- write a failing test firstin 176 of 439, across 112 files
- refactor code only after tests passin 171 of 439, across 101 files
- watch the test fail before writing codein 142 of 439, across 93 files
- test one behavior per testin 106 of 439, across 44 files
- refactor code while keeping tests greenin 99 of 439, across 86 files
- delete code written before testsin 98 of 439, across 54 files
- run tests after each refactor stephere, and in 85 of 439, across 54 files
- Use real code instead of mocks unless unavoidablein 64 of 439, across 21 files
- confirm the test fails for the right reasonin 64 of 439, across 60 files
- reproduce bugs with a test before fixingin 53 of 439, across 36 files
- write tests before implementationin 48 of 439, across 39 files
Said here and by no other author read
- remove duplication after passing
- improve names after passing
- simplify interfaces after passing
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once.