Test driven development
Eval-backed agent skills for Claude Code, Codex & OpenCode — for developers who hate skills.
npx -y skills add slowdini/slow-powers --skill test-driven-developmentAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 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
Use when implementing any feature, refactoring, or writing a bugfix.
SKILL.md
4.8 KB, as published. Nobody here has run it
Test-Driven Development (TDD)
Write the test first. Watch it fail. Write minimal code to pass. Refactor.
THE IRON LAW: NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST.
Write production code before the test? Delete it. Start over. Do not keep it for "reference" or "adapt" it. Delete means delete.
Violating the letter of the rules is violating the spirit of the rules.
REQUIRED PREREQUISITE: You must have already completed
slow-powers:working-in-isolation— establish an isolated workspace before writing any test or production code.
REQUIRED NEXT SKILL: You must complete
slow-powers:verifying-development-worknext, after the TDD implementation work is done and before claiming the task is complete or handing work back to the user.
Red-Green-Refactor Cycle
- RED — Write a Failing Test:
- Write one minimal, focused test showing what the behavior should do.
- Use real code and real inputs; avoid mocks unless absolutely unavoidable. Before committing a test, scan it against the Testing anti-patterns table below; if it matches a row, read the named section of the testing anti-patterns reference first.
- Verify RED — Watch It Fail:
- Run the test command:
npm test/pytest/go test. - MANDATORY: Verify it fails for the expected reason (e.g., function not defined, value incorrect), not due to a typo or build error.
- Run the test command:
- GREEN — Write Minimal Code:
- Write the simplest possible implementation to make the test pass.
- Avoid over-engineering or speculative optimization (YAGNI).
- Verify GREEN — Watch It Pass:
- Run the test suite. Verify the test passes, and no regressions are introduced.
- REFACTOR — Clean Up:
- Clean up names, remove duplication, and extract helper methods.
- Keep the test suite green. Do not add new behavior during refactoring.
Example: Code vs. Mock Testing
Good (Focuses on real behavior):
test('retries failed operations 3 times', async () => {
let attempts = 0;
const operation = async () => {
attempts++;
if (attempts < 3) throw new Error('fail');
return 'success';
};
const result = await retryOperation(operation);
expect(result).toBe('success');
expect(attempts).toBe(3);
});
Bad (Focuses on mock implementation detail):
test('retry works', async () => {
const mock = jest.fn()
.mockRejectedValueOnce(new Error())
.mockRejectedValueOnce(new Error())
.mockResolvedValueOnce('success');
await retryOperation(mock);
expect(mock).toHaveBeenCalledTimes(3);
});
Testing anti-patterns — scan before you commit a test
While writing or changing a test, check it against this table. If a row matches, read the named section of the testing anti-patterns reference before moving on — mocks are the most common source of these, but not the only one.
| If your test… | Anti-pattern | Section to read |
|---|---|---|
asserts on a mock / *-mock element instead of real output | testing mock behavior | Testing Mock Behavior |
| needs a method on a production class that only tests call | test-only methods in production | Test-Only Methods in Production |
| mocks a method without knowing its side effects | mocking without understanding | Mocking Without Understanding |
| uses a mock with only the fields you happen to need | incomplete mocks | Incomplete Mocks |
| is written after the implementation, with no failing test first | tests as afterthought | Tests as Afterthought |
stubs by call order (...Once chains) or asserts "call N" / "the last call" | order-dependent mocks/assertions | Order-Dependent Mocks and Assertions |
| has more mock setup than test logic | over-complex mocks | When Mocks Become Too Complex |
Common Rationalizations
| Excuse | Reality |
|---|---|
| "This is too simple to test" | Simple code breaks. Test takes 30 seconds. |
| "I'll test after to verify it works" | Tests passing immediately prove nothing. |
| "I already know what the code should look like" | Knowing the answer doesn't mean the requirement is specified. |
| "Testing this would be trivial" | Trivial tests are cheap; skipping them costs later. |
| "I'll add tests later, I promise" | Later never comes. The codebase drifts. |
| "The spirit of TDD is what matters, not the letter" | Violating the letter is violating the spirit. |
Red Flags — STOP and start over
- Code before test
- "I already manually tested it"
- "Tests after achieve the same purpose"
- "It's about spirit not ritual"
- "This is different because..."
All of these mean: delete code. Start over with TDD.