TDD Reference
Practical guidance for test-driven development: writing good tests, designing testable interfaces, mocking correctly, and refactoring safely.
Scope Constraints
- Read-only reference skill — provides guidance, does not modify code
- Does not run tests, generate test files, or configure test runners
- Complements
superpowers:test-driven-development workflow skill
Inputs
- Context (required): What the user is testing or designing
- Phase (optional):
red (writing failing test), green (making it pass), refactor (cleaning up)
Input Sanitization
- Context descriptions: free text, reject null bytes.
Procedure
- Identify the TDD phase. If unclear, ask: "Are you writing a new test, making one pass, or refactoring?"
- Load the reference file matching the phase or question:
- Writing tests →
references/tests.md
- Designing interfaces for testability →
references/interface-design.md
- Mocking decisions →
references/mocking.md
- Refactoring after green →
references/refactoring.md
- Module depth and API design →
references/deep-modules.md
- Apply the reference guidance to the user's specific code context.
- Flag anti-patterns from the loaded reference when found in user code.
Output Format
## TDD Guidance: [phase/topic]
[Specific advice applied to user's code context]
Pattern: [recommended approach]
Anti-pattern: [what to avoid and why]
Reference: [which reference file was consulted]
Gotchas
- Tests that assert implementation details (e.g., checking internal method calls) break on every refactor — test behavior and outputs, not how the code does it
- Mocking at the wrong boundary (e.g., mocking the function under test, or mocking too deep) — mock at system boundaries (HTTP, DB, filesystem), not internal modules
- Assertion-free "tests" that just call code without checking results — every test needs at least one meaningful assertion
beforeAll shared state between tests causes order-dependent failures — prefer beforeEach for fresh state per test
- Testing private methods directly indicates poor interface design — if you need to test it, it should be part of the public API
- Snapshot tests that get
--updated without review become rubber stamps — review every snapshot diff carefully
// WRONG: testing implementation details
expect(service.internalCache.size).toBe(3);
// RIGHT: testing behavior
expect(await service.getUser("abc")).toEqual({ id: "abc", name: "Alice" });
// WRONG: mocking the thing you're testing
vi.spyOn(calculator, 'add').mockReturnValue(5);
expect(calculator.add(2, 3)).toBe(5); // tests nothing
// RIGHT: mock dependencies, test the unit
vi.spyOn(httpClient, 'get').mockResolvedValue({ rate: 1.5 });
expect(await converter.convert(100, 'USD', 'EUR')).toBe(150);
References
| Path |
Load Condition |
Content Summary |
references/tests.md |
Writing or reviewing tests |
Good vs bad test patterns, quality table, examples |
references/mocking.md |
Mock decisions or test setup |
When to mock, anti-patterns, dependency injection |
references/interface-design.md |
Designing testable code |
DI, return values over side effects, surface area |
references/refactoring.md |
After green phase |
Refactor candidates checklist |
references/deep-modules.md |
API/module design |
Deep vs shallow modules, interface simplification |
1---2name: tdd3description: >4 Test-driven development reference for writing good tests, designing testable5 interfaces, mocking at system boundaries, and refactoring after green. Use when6 writing tests, reviewing test quality, or applying red-green-refactor workflow.7 Not for running test suites or CI configuration — use language-conventions or8 cicd-generation for those.9model:10 preferred: sonnet11 acceptable: [sonnet, opus]12 minimum: sonnet13 allow_downgrade: true14 reasoning_demand: low15---1617# TDD Reference1819Practical guidance for test-driven development: writing good tests, designing testable interfaces, mocking correctly, and refactoring safely.2021## Scope Constraints2223- Read-only reference skill — provides guidance, does not modify code24- Does not run tests, generate test files, or configure test runners25- Complements `superpowers:test-driven-development` workflow skill2627## Inputs2829- **Context** (required): What the user is testing or designing30- **Phase** (optional): `red` (writing failing test), `green` (making it pass), `refactor` (cleaning up)3132## Input Sanitization3334- Context descriptions: free text, reject null bytes.3536## Procedure37381. Identify the TDD phase. If unclear, ask: "Are you writing a new test, making one pass, or refactoring?"392. Load the reference file matching the phase or question:40 - Writing tests → `references/tests.md`41 - Designing interfaces for testability → `references/interface-design.md`42 - Mocking decisions → `references/mocking.md`43 - Refactoring after green → `references/refactoring.md`44 - Module depth and API design → `references/deep-modules.md`453. Apply the reference guidance to the user's specific code context.464. Flag anti-patterns from the loaded reference when found in user code.4748## Output Format4950```51## TDD Guidance: [phase/topic]5253[Specific advice applied to user's code context]5455 Pattern: [recommended approach]56 Anti-pattern: [what to avoid and why]5758Reference: [which reference file was consulted]59```6061## Gotchas6263- Tests that assert implementation details (e.g., checking internal method calls) break on every refactor — test behavior and outputs, not how the code does it64- Mocking at the wrong boundary (e.g., mocking the function under test, or mocking too deep) — mock at system boundaries (HTTP, DB, filesystem), not internal modules65- Assertion-free "tests" that just call code without checking results — every test needs at least one meaningful assertion66- `beforeAll` shared state between tests causes order-dependent failures — prefer `beforeEach` for fresh state per test67- Testing private methods directly indicates poor interface design — if you need to test it, it should be part of the public API68- Snapshot tests that get `--update`d without review become rubber stamps — review every snapshot diff carefully6970```typescript71// WRONG: testing implementation details72expect(service.internalCache.size).toBe(3);73// RIGHT: testing behavior74expect(await service.getUser("abc")).toEqual({ id: "abc", name: "Alice" });7576// WRONG: mocking the thing you're testing77vi.spyOn(calculator, 'add').mockReturnValue(5);78expect(calculator.add(2, 3)).toBe(5); // tests nothing79// RIGHT: mock dependencies, test the unit80vi.spyOn(httpClient, 'get').mockResolvedValue({ rate: 1.5 });81expect(await converter.convert(100, 'USD', 'EUR')).toBe(150);82```8384## References8586| Path | Load Condition | Content Summary |87|------|---------------|-----------------|88| `references/tests.md` | Writing or reviewing tests | Good vs bad test patterns, quality table, examples |89| `references/mocking.md` | Mock decisions or test setup | When to mock, anti-patterns, dependency injection |90| `references/interface-design.md` | Designing testable code | DI, return values over side effects, surface area |91| `references/refactoring.md` | After green phase | Refactor candidates checklist |92| `references/deep-modules.md` | API/module design | Deep vs shallow modules, interface simplification |