tdd
Use when implementing any feature or bugfix, before writing implementation code. Enforces strict test-first development — no production code without a failing test.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when implementing any feature or bugfix, before writing implementation code. Enforces strict test-first development — no production code without a failing test.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | tdd |
| description | Use when implementing any feature or bugfix, before writing implementation code. Enforces strict test-first development — no production code without a failing test. |
Write the test first. Watch it fail. Write minimal code to pass.
Core principle: Without watching the test fail first, the test's correctness is unknown — a passing test that was never seen failing might be vacuous.
Violating the letter of the rules is violating the spirit of the rules.
Always:
Exceptions (ask the human partner first):
The thought "skip TDD just this once" is rationalization — stop and reconsider.
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
Write code before the test? Delete it. Start over.
No exceptions:
Implement fresh from tests. Period.
Every piece of production code follows this cycle. No shortcuts. No reordering.
Write one minimal test that describes the behavior you want.
Requirements:
# Test describes the WHAT, not the HOW
# Name states expected behavior clearly
# Tests real code, not mock behavior
Bad tests: vague names, multiple assertions testing unrelated things, mocking away the code under test.
Why mocks are last resort: a mock asserts what the test author thinks the dependency does. When the real dependency drifts, the mock keeps passing while production breaks.
MANDATORY. Never skip.
Run the project's test command targeting your new test.
Confirm:
Test passes immediately? It is testing existing behavior — the test is wrong. Fix it.
Test errors instead of failing? Fix the error. Re-run until it fails correctly — a clean failure for the right reason.
Write the simplest possible code to make the test pass. Nothing more.
If the test asks for one thing, implement one thing.
MANDATORY.
Run the project's test command.
Confirm:
New test fails? Fix the implementation, not the test.
Other tests broke? Fix them now. Do not proceed with broken tests.
Only after green:
Run the project's test command after every change. Stay green. If tests break during refactor, undo and try again.
Do NOT add behavior during refactor. Refactor changes structure, not functionality.
Next failing test. Next behavior. Same cycle. No exceptions.
Write code before the test? Delete it. Start over. No exceptions.
200 lines without a test? Delete 200 lines. 4 hours spent? Those hours are gone regardless. Two options remain:
Option 2 is not TDD. It is rationalization wearing a lab coat.
Every excuse below is invalid. Every single one.
| Excuse | Reality |
|---|---|
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. Write it. |
| "I'll test after" | Tests passing immediately prove nothing. The proof is lost. |
| "Tests after achieve same goals" | Tests-after = "what does this do?" Tests-first = "what should this do?" Different questions. |
| "Already manually tested" | Ad-hoc is not systematic. No record. Can't re-run. Can't trust. |
| "Deleting X hours is wasteful" | Sunk cost fallacy. The time is gone. Keeping unverified code is debt. |
| "Keep as reference" | Adaptation creeps in — that's testing-after with extra steps. Delete means delete. |
| "Need to explore first" | Fine. Explore. Then throw away ALL exploration code and start with TDD. |
| "Test is hard = design unclear" | Listen to the test. Hard to test = hard to use. Fix the design. |
| "TDD will slow me down" | TDD is faster than debugging. The time gets paid either way — upfront or in production. |
| "Manual test is faster" | Manual doesn't prove edge cases. Manual means re-testing every change forever. |
| "Existing code has no tests" | Add tests for the code being touched. No excuse. |
| "This is different because..." | It's not. Delete the code. Start over with TDD. |
"I'll write tests after to verify it works"
Tests written after code pass immediately. Passing immediately proves nothing:
Test-first forces seeing the test fail, proving it actually tests something real.
"Tests after achieve the same goals — it's spirit not ritual"
No. Tests-after are biased by the implementation already in front of them. They verify what was built, not what's required. They check remembered edge cases, not discovered ones.
Tests-first force edge case discovery BEFORE implementing. Tests-after assume nothing was forgotten — that assumption rarely holds.
"Deleting X hours of work is wasteful"
Sunk cost fallacy. The time is already spent. Two options remain:
The "waste" is keeping code that cannot be trusted.
"TDD is dogmatic, being pragmatic means adapting"
TDD IS pragmatic:
"Pragmatic" shortcuts = debugging in production = slower.
Stop immediately on any of these. Delete the code. Restart with TDD.
All of these mean the same thing: Delete the code. Start over with TDD.
No negotiation. No partial credit. Delete and restart.
| Quality | Good | Bad |
|---|---|---|
| Minimal | Tests one thing. "and" in name? Split it. | test('validates email and domain and whitespace') |
| Clear | Name describes expected behavior | test('test1'), test('it works') |
| Intent | Demonstrates the desired API | Obscures what code should do |
| Real | Tests actual code paths | Tests mock behavior instead of real behavior |
| Focused | Assertion matches the test name | Asserts unrelated side effects |
| Problem | Solution |
|---|---|
| Don't know how to test | Write the API the test wishes existed. Write the assertion first. Ask the human partner. |
| Test too complicated | Design too complicated. Simplify the interface. |
| Must mock everything | Code too coupled. Use dependency injection. Reduce coupling. |
| Test setup is huge | Extract test helpers. Still complex? Simplify the design. |
| Can't isolate the unit | Break dependencies. Inject them. Make the boundary explicit. |
Bug found? Write a failing test that reproduces it FIRST. Then follow the TDD cycle. The test proves the fix works AND prevents regression.
Never fix bugs without a test. The test is the proof. Without proof, the fix is a guess.
Before marking any task complete, confirm ALL of these:
Any unchecked box means TDD was skipped — start over.
Production code -> test exists and failed first
Otherwise -> not TDD
No exceptions without explicit permission from the human partner.
Use before any creative work — features, components, changes, or modifications. Guides structured design through collaborative dialogue before implementation. Triggers: "brainstorm", "design", "think through", "explore approaches", ambiguous requests, or requests with multiple valid interpretations.
Use after a problem has been solved and the solution verified working — captures the lesson as categorized documentation in docs/solutions/ with YAML frontmatter so future sessions can find it. Triggers: "compound", "capture learning", "document solution", "that worked", "it's fixed", "working now", "problem solved", "that did it", "doc-fix".
Use for extended multi-agent review with 14+ agents including conditional and language-specific reviewers. Appropriate for large changes, architectural shifts, migrations, or when standard review is not thorough enough. Triggers: "deep review", "thorough review", "full review", "extended review", "review everything", "maximum coverage".
Use to review brainstorm or plan documents before proceeding to the next workflow step. Applies structured self-review for completeness, clarity, consistency, feasibility, and YAGNI.
Use when implementation is complete and all tests pass — guides branch completion by presenting structured options for merge, PR, or cleanup.
Use when performing multi-agent code review after implementing features, before merging, or when reviewing PRs. Runs 5 core review agents in parallel plus a learnings researcher. Produces prioritized findings (P1/P2/P3) with todo files for tracking and resolution. Triggers: "review", "code review", "check before merge", "review PR", "run reviewers", "catch issues".