working-with-tdd
Skill2 starsChanged 50 days agoMITView on GitHub
Use when implementing any feature, refactoring, or writing a bugfix.
In this repository10 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- auditing-slow-powers-usageSkill
- evaluating-skillsSkill
- hardening-plansSkill
- investigating-bugsSkill
- verifying-development-workSkill
- working-in-isolationSkill
- writing-skillsSkill
- writing-technical-docsSkill
The file
We split this skill into the rules it gives an agent
12 rules. About 0 are common, 11 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈11
Distinctive · estimate
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
- Distinctive: line 8
Write the test first. Watch it fail.
- Distinctive: line 12
Write production code before the test?
- Distinctive: line 25
Write one minimal, focused test showing what the behavior *should* do.
- Distinctive: line 26
Use real code and real inputs.
- Distinctive: line 27
Before committing a test, scan it against the Testing anti-patterns table below.
- Very specific: line 31
Run the test command: npm test / pytest / go test.
- Distinctive: line 32
MANDATORY: Verify it fails for the expected reason (for example, a function is undefined or a value is incorrect), not because of a typo or …
- Distinctive: line 34
Write the simplest possible implementation to make the test pass.
- Distinctive: line 35
Avoid over-engineering or speculative optimization.
- Distinctive: line 37
Run the test suite. Verify the test passes, and no regressions are introduced.
- Distinctive: line 40
Keep the test suite green.
- Distinctive: line 112
All of these mean: delete code.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “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)
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 (for example, a function is undefined or a value is incorrect), not because of 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.
- 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.
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.

