Test-Driven Development
Memorable invocation: $tdd
Use this skill to move in small, verified behavior slices:
RED -> GREEN -> REFACTOR -> repeat
Before writing or changing tests, mocks, or test helpers, apply
Writing Good Tests.
Core Loop
- Choose one observable behavior.
- For a bug fix, first express the reported failure as one failing regression test.
- For a feature or behavior change, start with the smallest user-visible or public-interface behavior.
- Prefer tests through public interfaces and real code paths over tests coupled to private implementation details.
- Before writing the test body, name a realistic production break it should catch. If only an intentional source or private-structure change would fail it, redesign the test around observable behavior.
- RED: write one failing test.
- Use literal expected values or independently hand-checked fixtures when practical. Do not compute expectations through the implementation or helper under test, except in an explicitly named characterization test with independent evidence.
- Run the new test with the repo's narrowest relevant test invocation. Start from
.agents/bin/test when present, then narrow using the repo's test framework convention.
- Confirm the test fails for the right reason: the missing behavior or reproduced bug.
- If it fails because of a typo, missing import, bad fixture, or harness problem, fix the test setup before touching production code.
- If it passes immediately, do not proceed to GREEN: the test describes existing behavior; tighten or replace it until you have watched the intended failure.
- GREEN: write the smallest production change that makes that test pass.
- Do not add production code before a failing test exists.
- Do not add speculative behavior for future tests.
- Rerun the same targeted test and confirm it passes.
- REFACTOR: improve while green.
- Remove duplication, clarify names, and simplify structure only with tests passing.
- Rerun the targeted test after each meaningful refactor step.
- Repeat with the next behavior.
- Add one new failing test at a time.
- Keep each cycle narrow enough that a failure clearly points to the current behavior.
Guardrails
- Never refactor while RED.
- Never batch-write all tests before implementation; use vertical slices.
- Never claim a bug is fixed without evidence: prefer a regression test that failed before the fix and passes after it.
- Exact source, text, path, and mirror checks prove source or packaging invariants only. For a behavior claim, execute the artifact or pressure-test its consumer when practical.
- Preserve real side effects needed by the behavior. Mock only slow or external boundaries, use realistic complete doubles, and do not treat a mock's existence as behavioral proof.
- Before completion, choose a small finite set of realistic failure modes for the changed behavior and confirm the relevant test fails for them. This bounded mutation check needs no mutation-testing software.
- Only when a direct automated regression test is not practical, document why, then use the closest useful local verification through
.agents/bin/test or the repo's documented manual surface to capture before and after behavior.
- Before handoff or PR creation, run
.agents/bin/validate in addition to the targeted tests used during the loop.
Before Pushing
- If the change affects a developer workflow, exercise that workflow with
.agents/bin/test or the repo's relevant local verification rather than relying only on unit tests.
- If the change affects app-facing behavior, do minimal manual verification through the repo's relevant local app or manual-test surface when appropriate.
- Try to run the same relevant local tests that CI would run for the changed area before pushing, then run
.agents/bin/validate.
Done
The loop is complete when each observable behavior specified in the task or issue has passing test coverage, or documented before-and-after closest-useful verification only when a direct automated regression test is not practical, and the pre-push validation passes clean. Report the behaviors implemented, the tests added, any fallback verification rationale and before/after result, and the result of the pre-push validation.
1---2name: tdd3description: Drive a portable red-green-refactor workflow for features, bug fixes, and changes to existing behavior. Use when implementing behavior with test-driven development, reproducing a bug as a failing test before fixing it, changing the semantics of existing code, or when the user asks for TDD, test-first, or red-green-refactor discipline.4---56# Test-Driven Development78<!-- Keep this skill in sync with `workflows/tdd.md`. -->910Memorable invocation: `$tdd`1112Use this skill to move in small, verified behavior slices:1314```text15RED -> GREEN -> REFACTOR -> repeat16```1718Before writing or changing tests, mocks, or test helpers, apply19[Writing Good Tests](references/writing-good-tests.md).2021## Core Loop22231. Choose one observable behavior.24 - For a bug fix, first express the reported failure as one failing regression test.25 - For a feature or behavior change, start with the smallest user-visible or public-interface behavior.26 - Prefer tests through public interfaces and real code paths over tests coupled to private implementation details.27 - Before writing the test body, name a realistic production break it should catch. If only an intentional source or private-structure change would fail it, redesign the test around observable behavior.282. RED: write one failing test.29 - Use literal expected values or independently hand-checked fixtures when practical. Do not compute expectations through the implementation or helper under test, except in an explicitly named characterization test with independent evidence.30 - Run the new test with the repo's narrowest relevant test invocation. Start from `.agents/bin/test` when present, then narrow using the repo's test framework convention.31 - Confirm the test fails for the right reason: the missing behavior or reproduced bug.32 - If it fails because of a typo, missing import, bad fixture, or harness problem, fix the test setup before touching production code.33 - If it passes immediately, do not proceed to GREEN: the test describes existing behavior; tighten or replace it until you have watched the intended failure.343. GREEN: write the smallest production change that makes that test pass.35 - Do not add production code before a failing test exists.36 - Do not add speculative behavior for future tests.37 - Rerun the same targeted test and confirm it passes.384. REFACTOR: improve while green.39 - Remove duplication, clarify names, and simplify structure only with tests passing.40 - Rerun the targeted test after each meaningful refactor step.415. Repeat with the next behavior.42 - Add one new failing test at a time.43 - Keep each cycle narrow enough that a failure clearly points to the current behavior.4445## Guardrails4647- Never refactor while RED.48- Never batch-write all tests before implementation; use vertical slices.49- Never claim a bug is fixed without evidence: prefer a regression test that failed before the fix and passes after it.50- Exact source, text, path, and mirror checks prove source or packaging invariants only. For a behavior claim, execute the artifact or pressure-test its consumer when practical.51- Preserve real side effects needed by the behavior. Mock only slow or external boundaries, use realistic complete doubles, and do not treat a mock's existence as behavioral proof.52- Before completion, choose a small finite set of realistic failure modes for the changed behavior and confirm the relevant test fails for them. This bounded mutation check needs no mutation-testing software.53- Only when a direct automated regression test is not practical, document why, then use the closest useful local verification through `.agents/bin/test` or the repo's documented manual surface to capture before and after behavior.54- Before handoff or PR creation, run `.agents/bin/validate` in addition to the targeted tests used during the loop.5556## Before Pushing5758- If the change affects a developer workflow, exercise that workflow with `.agents/bin/test` or the repo's relevant local verification rather than relying only on unit tests.59- If the change affects app-facing behavior, do minimal manual verification through the repo's relevant local app or manual-test surface when appropriate.60- Try to run the same relevant local tests that CI would run for the changed area before pushing, then run `.agents/bin/validate`.6162## Done6364The loop is complete when each observable behavior specified in the task or issue has passing test coverage, or documented before-and-after closest-useful verification only when a direct automated regression test is not practical, and the pre-push validation passes clean. Report the behaviors implemented, the tests added, any fallback verification rationale and before/after result, and the result of the pre-push validation.