From tdd
Use TDD for all code-writing tasks. TRIGGER when the user asks to implement, build, create, fix, refactor, or write any code — features, bug fixes, refactors, APIs, utilities, etc. DO NOT TRIGGER when the user is only debugging (reading logs, inspecting state, tracing execution), asking questions about code without wanting changes, doing exploratory/spike work, or writing tests for already-existing code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/tdd:tddThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Strict TDD mode. Every line of production code must be justified by a failing test — this
Strict TDD mode. Every line of production code must be justified by a failing test — this constraint is what makes TDD valuable, because it guarantees that tests actually verify behaviour rather than just existing alongside code.
Follow this cycle for every behaviour. Never skip a phase.
test_returns_empty_list_when_no_items_match).Run the test and confirm the assertion failure before moving to Green. Skipping this step defeats the purpose of TDD — an unverified red phase means there's no proof the test can catch a regression. A compile or link error is NOT a valid red — it proves nothing about behaviour.
Run all tests and confirm they pass before moving to Refactor.
Run tests after every refactoring change to confirm they still pass.
No production code without a failing test. This is TDD's core discipline. If there's an urge to write implementation code, channel it into writing a test first.
Run real tests every time. Use the project's actual test runner. Never simulate or assume test output — the whole point is to let real test results drive decisions.
Minimise mocking. Mocks lie about how the system actually works. Only mock at hard architectural boundaries (external HTTP APIs, databases without in-memory alternatives, filesystem when truly necessary, system clock/randomness). If it can be tested with real code, test it with real code.
Keep steps small. Each cycle should touch a small, focused behaviour. Needing more than ~10 lines of production code to pass a test usually means the test covers too much.
Maintain a test list. Before starting, brainstorm the behaviours to test and write them as a checklist ordered from simplest to most complex. Update the list as new cases are discovered or existing ones are completed. Share the list with the user.
Refactor tests too. When test setup becomes repetitive or helper functions could be clearer, refactor them with the same rigour as production code.
Announce the phase. Before each action, state the current phase:
RED: Writing a test for [behaviour]GREEN: Writing minimum code to passREFACTOR: [what is being improved]When beginning a TDD task:
Understand the goal. Read existing code, understand the requirement. Ask clarifying questions if the desired behaviour is ambiguous.
Detect the test framework. Check existing test files, package.json,
pyproject.toml, Cargo.toml, go.mod, Gemfile, build.gradle, or equivalent.
Use whatever framework and conventions the project already uses. If no tests exist,
ask the user which framework to use.
Brainstorm the test list. List behaviours from simplest to most complex. Start with degenerate cases (empty input, zero, null) and build toward core logic. Share the list with the user.
Start the first Red-Green-Refactor cycle with the simplest test from the list.
The task is done when:
Run the full test suite one final time to confirm everything passes.
npx claudepluginhub mdodkins/claude-tdd-skill --plugin tddRed-Green-Refactor cycle for test-first development. Write failing test, implement minimal code, refactor safely. Use when developing new features or fixing bugs in test-driven projects.