Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Enforce red-green-refactor in small vertical slices through public interfaces.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: tdd3description: Test-driven development with red-green-refactor loop. Use when user wants to build features or fix bugs using TDD, mentions "red-green-refactor", wants integration tests, or asks for test-first development.4---56# Test-Driven Development78## Philosophy910**Core principle**: Tests should verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't.1112**Good tests** are integration-style: they exercise real code paths through public APIs. They describe _what_ the system does, not _how_ it does it. A good test reads like a specification - "user can checkout with valid cart" tells you exactly what capability exists. These tests survive refactors because they don't care about internal structure.1314**Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior.1516See [tests.md](tests.md) for examples and [mocking.md](mocking.md) for mocking guidelines.1718## Anti-Pattern: Horizontal Slices1920**DO NOT write all tests first, then all implementation.** This is "horizontal slicing" - treating RED as "write all tests" and GREEN as "write all code."2122This produces **crap tests**:2324- Tests written in bulk test _imagined_ behavior, not _actual_ behavior25- You end up testing the _shape_ of things (data structures, function signatures) rather than user-facing behavior26- Tests become insensitive to real changes - they pass when behavior breaks, fail when behavior is fine27- You outrun your headlights, committing to test structure before understanding the implementation2829**Correct approach**: Vertical slices via tracer bullets. One test → one implementation → repeat. Each test responds to what you learned from the previous cycle. Because you just wrote the code, you know exactly what behavior matters and how to verify it.3031```32WRONG (horizontal):33RED: test1, test2, test3, test4, test534GREEN: impl1, impl2, impl3, impl4, impl53536RIGHT (vertical):37RED→GREEN: test1→impl138RED→GREEN: test2→impl239RED→GREEN: test3→impl340...41```4243## Workflow4445### 1. Planning4647Before writing any code:4849- [ ] Confirm with user what interface changes are needed50- [ ] Confirm with user which behaviors to test (prioritize)51- [ ] Identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation)52- [ ] Design interfaces for [testability](interface-design.md)53- [ ] List the behaviors to test (not implementation steps)54- [ ] Get user approval on the plan5556Ask: "What should the public interface look like? Which behaviors are most important to test?"5758**You can't test everything.** Confirm with the user exactly which behaviors matter most. Focus testing effort on critical paths and complex logic, not every possible edge case.5960### 2. Tracer Bullet6162Write ONE test that confirms ONE thing about the system:6364```65RED: Write test for first behavior → test fails66GREEN: Write minimal code to pass → test passes67```6869This is your tracer bullet - proves the path works end-to-end.7071### 3. Incremental Loop7273For each remaining behavior:7475```76RED: Write next test → fails77GREEN: Minimal code to pass → passes78```7980Rules:8182- One test at a time83- Only enough code to pass current test84- Don't anticipate future tests85- Keep tests focused on observable behavior8687### 4. Refactor8889After all tests pass, look for [refactor candidates](refactoring.md):9091- [ ] Extract duplication92- [ ] Deepen modules (move complexity behind simple interfaces)93- [ ] Apply SOLID principles where natural94- [ ] Consider what new code reveals about existing code95- [ ] Run tests after each refactor step9697**Never refactor while RED.** Get to GREEN first.9899## Checklist Per Cycle100101```102[ ] Test describes behavior, not implementation103[ ] Test uses public interface only104[ ] Test would survive internal refactor105[ ] Code is minimal for this test106[ ] No speculative features added107```108