← marketplace
engineersconceptsha:16d0a165ab45e243manual
mp-tdd
Use when building features or fixing bugs test-first — red-green-refactor in vertical tracer-bullet slices, tests verifying behavior through public interfaces so they survive internal refactors.
source: https://github.com/mattpocock/skills/blob/main/skills/engineering/tdd/SKILL.md ↗mattpocock/skills· ★ 76k
Tutorials · creator-attached
One-line install
curl --create-dirs -fsSL https://skillmake.xyz/i/mp-tdd -o ~/.claude/skills/mp-tdd/SKILL.md
The hash above pins this exact content. The file we serve at /api/marketplace/mp-tdd-16d0a165/raw always matches sha:16d0a165ab45e243.
5,470 chars · ~1,368 tokens
--- name: mp-tdd description: Use when building features or fixing bugs test-first — red-green-refactor in vertical tracer-bullet slices, tests verifying behavior through public interfaces so they survive internal refactors. source: https://github.com/mattpocock/skills/blob/main/skills/engineering/tdd/SKILL.md generated: 2026-05-12T18:05:20.493Z category: concept audience: engineers --- ## Tutorials - https://skillmake.xyz/v/mp-tdd.mp4 ## When to use - Adding a new feature where you want behavior locked down before the implementation drifts - Fixing a bug by writing the regression test first, then the fix - User explicitly says 'red-green-refactor', 'TDD this', or 'test-first' - Replacing implementation-coupled tests that break on refactor with integration-style behavior tests ## Key concepts ### behavior over implementation Tests verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't. A good test reads like a specification — 'user can checkout with valid cart' tells you exactly what capability exists. If renaming an internal function breaks the test, it was testing implementation. ### good vs bad tests Good tests are integration-style: exercise real code paths through public APIs, describe WHAT the system does. Bad tests are coupled to implementation: mock internal collaborators, test private methods, or verify through external means (querying the DB directly instead of using the interface). Warning sign: test breaks on refactor while behavior is unchanged. ### horizontal-slice anti-pattern DO NOT write all tests first, then all implementation. Bulk-writing tests produces tests of IMAGINED behavior — shape of data structures, function signatures — not actual user-facing behavior. They become insensitive to real changes (pass when behavior breaks, fail when it's fine) because you committed to test structure before understanding the implementation. ### vertical tracer-bullet slice 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. This is the correct shape of red-green-refactor. ### the tracer bullet (first cycle) Write ONE test that confirms ONE thing about the system. RED: write the test → it fails. GREEN: minimal code to pass → it passes. This proves the path works end-to-end before you scale up. Then incremental loop: one test, minimal code, again. ### deep modules + interface design Before writing code, look for opportunities to create deep modules — small interface, deep implementation. Design interfaces FOR testability. The interface is the test surface, so getting it right means tests will actually survive. ### refactor only on GREEN After all tests pass, look for refactor candidates — extract duplication, deepen modules, apply SOLID where natural. Run tests after each refactor step. Never refactor while RED — get to GREEN first. ## API reference ``` Horizontal (WRONG) vs Vertical (RIGHT) workflow ``` The shape of the loop is the whole skill. Horizontal slicing produces crap tests; vertical tracer bullets produce tests that survive refactors. ``` WRONG (horizontal): RED: test1, test2, test3, test4, test5 GREEN: impl1, impl2, impl3, impl4, impl5 RIGHT (vertical): RED→GREEN: test1→impl1 RED→GREEN: test2→impl2 RED→GREEN: test3→impl3 ... ``` ``` Planning checklist (before any code) ``` Reach agreement on the interface and which behaviors matter most before writing the first test. You can't test everything — focus testing effort on critical paths and complex logic. ``` - [ ] Confirm with user what interface changes are needed - [ ] Confirm with user which behaviors to test (prioritize) - [ ] Identify opportunities for deep modules (small interface, deep implementation) - [ ] Design interfaces for testability - [ ] List the behaviors to test (not implementation steps) - [ ] Get user approval on the plan Ask: "What should the public interface look like? Which behaviors are most important to test?" ``` ``` Per-cycle checklist ``` Run this against every single tracer bullet cycle so tests don't drift into implementation-coupling. ``` [ ] Test describes behavior, not implementation [ ] Test uses public interface only [ ] Test would survive internal refactor [ ] Code is minimal for this test [ ] No speculative features added ``` ## Gotchas - Don't write all tests first then all implementation — bulk tests test imagined behavior, not actual behavior. - If renaming an internal function breaks a test while behavior is unchanged, the test was implementation-coupled. - Mocking internal collaborators is a smell. Prefer integration-style tests through public APIs. - Never refactor while RED. Get to GREEN first, then refactor with the test net in place. - Write only enough code to pass the current test. Don't anticipate future tests. - You can't test everything. Confirm with the user which behaviors matter most before writing tests. - Verifying through external means (querying the DB instead of using the interface) couples tests to implementation. - Run tests after each refactor step, not at the end — small reversible moves keep refactoring safe. --- Generated by SkillMake from https://github.com/mattpocock/skills/blob/main/skills/engineering/tdd/SKILL.md on 2026-05-12T18:05:20.493Z. Verify against source before relying on details.
File: ~/.claude/skills/mp-tdd/SKILL.md