tdd-expert
Drive development with strict Red-Green-Refactor discipline - write one failing test, write the minimum code to pass it, refactor on green - including test-list planning and a worked kata cycle. Use when someone asks "write this test-first", "do TDD on this feature", "help me practice red-green-refactor", "write a failing test for this bug", or wants tests to drive a new module's design. Do NOT use for adding tests to existing untested legacy code before a refactor - use characterization-test-writer instead - or for designing shared fixtures and factories - use test-data-builder instead.
- License 许可
- MIT
- 最近更新
- 2026-10-14
- Stars
- ★ 25
- Forks
- 3
01 前言 Front Matter
- name
- tdd-expert
- metadata
- { "title": "TDD Expert" }
- description
- Drive development with strict Red-Green-Refactor discipline - write one failing test, write the minimum code to pass it, refactor on green - including test-list planning and a worked kata cycle. Use when someone asks "write this test-first", "do TDD on this feature", "help me practice red-green-refactor", "write a failing test for this bug", or wants tests to drive a new module's design. Do NOT use for adding tests to existing untested legacy code before a refactor - use characterization-test-writer instead - or for designing shared fixtures and factories - use test-data-builder instead.
03 SKILL.md 正文
TDD Expert
Test-driven development produces code where every line exists because a test demanded it - which means every line is covered, the design is testable by construction, and refactoring is safe. The costly mistake this skill prevents is writing production code ahead of the tests: untested branches accumulate, the tests become an afterthought that mirrors the implementation, and the safety net has holes exactly where the bugs are.
Operating procedure
Order is the whole method - each step is only safe because the previous one finished.
Step 1: Gather inputs and write the test list
Before any test, collect: the behavior being built (one sentence), the interface it will be called through, and the known edge cases. Then write the test list: a plain bullet list of every behavior and edge case you can think of - happy path, empty input, boundaries, error cases. This is planning, not test code; add to it whenever a new case occurs to you mid-cycle instead of breaking the current cycle to chase it. If requirements are ambiguous, write the ambiguity into the list as a question and pick a defensible default, labeled as a guess.
Step 2: Red
Pick ONE item from the list - the simplest one that teaches you something. Write one failing test that describes the desired behavior through the public interface. Run it and watch it fail with the failure you expected. A test you never saw fail proves nothing: it may be testing nothing, or passing for the wrong reason.
Step 3: Green
Write the minimum code to pass - ugly, hardcoded, whatever. Minimum means minimum: hardcoding the expected return value is correct at this stage; the next test will force the generalization. Never write production code without a failing test that requires it, and never write ahead of the current test.
Step 4: Refactor
Only with all tests green: remove duplication, improve names, extract structure. Do not add behavior - behavior changes require going back to Red. Run the tests after every refactoring move.
Step 5: Repeat until the list is empty
Cross off the item, pick the next. When the list is empty and no new cases occur to you, the feature is done - by definition, with full coverage.
Worked cycle - leading-zeros kata (wordCount)
Item from the test list: "empty string has zero words."
Red - write the failing test:
test('empty string has zero words', () => {
expect(wordCount('')).toBe(0)
})
// FAIL: wordCount is not defined ← watched it fail
Green - minimum code, hardcoded is correct:
function wordCount(s) { return 0 }
// PASS
Next Red - force generalization with the next list item:
test('single word counts as one', () => {
expect(wordCount('hello')).toBe(1)
})
// FAIL: expected 1, received 0
Green - now the hardcode must die:
function wordCount(s) { return s === '' ? 0 : s.split(' ').length }
// both PASS
Refactor - on green, clean up (handle multiple spaces when the test list demands it, not before):
function wordCount(s) {
const words = s.trim().split(/\s+/).filter(Boolean)
return words.length
}
// all PASS - only after a "multiple spaces between words" test went red first
That is one full turn of the crank: fail for the expected reason, pass with the least code, refactor with the net up.
Thresholds
- One logical assertion per test where possible; multiple asserts are acceptable only when they verify one behavior (e.g., several fields of one returned object).
- Unit test budget: each test under 100ms, the whole unit suite under 10 seconds locally - slower suites stop getting run on every Green, which breaks the loop.
- No I/O (network, disk, real clock) in unit tests unless the I/O is the behavior under test.
- Cycle length: if you have been in Red for more than about 10 minutes, the step is too big - delete the test, pick a smaller item from the list.
- Test names read like specifications: "returns zero for empty cart," not "test1".
When TDD applies
- Strongest: new features with clear requirements, complex business logic, API contract development, and bug fixes - for a bug, first write a test that reproduces it, watch it fail, then fix.
- Weaker: exploratory spikes (write them without tests, then throw the spike away and TDD the real version), UI layout changes, simple CRUD with no logic.
- Legacy code with no tests: do not start here. Pin current behavior first with characterization-test-writer, then TDD the change inside that net. If you cannot write a test for the code at all, the design is wrong - fix the seam before the feature.
Deliverable
Produce the test list, then the code and tests grown one Red-Green-Refactor cycle at a time, with the final suite green and each test readable as a one-line specification of behavior.
Do NOT
- Do not write production code without a failing test that demands it - that code is unverified by construction.
- Do not write several tests ahead; batching hides which test forced which code and stalls the feedback loop.
- Do not refactor while red - you cannot tell whether a break came from the cleanup or the unfinished feature.
- Do not skip watching the test fail; a never-failed test may pass vacuously.
- Do not test implementation details (private methods, call counts on internals) - test behavior through the public interface, or every refactor breaks the suite.
- Do not "improve" the code during Green beyond what passes the test; generalization belongs to the next Red.
Quality bar
- Every production line traceable to a test that failed without it.
- Test list fully crossed off, including error and boundary cases.
- Suite meets the runtime budget and passes deterministically (no order dependence, no shared mutable state).
- Each test asserts one behavior and names it as a specification.
- No test knows anything a caller of the public interface would not know.
04 同仓库更多 Skills
有氧运动计划
zone-2-cardio-plan
当有人要求制定稳态有氧训练计划、进行有氧基础训练或达到第二区间、安排轻松或耐力型的每周有氧训练、按心率区间训练,或提高静息心率、最大摄氧量或耐力时,可以使用此方案。该方案构建了一个包含训练计划结构、训练方式选择和进度安排的心率区间有氧训练模块。本方案仅提供一般健身指导,不构成医疗建议。请勿用于设计力量或举重训练计划(请使用力量训练计划)、高强度间歇训练 (HIIT) 或循环训练(请使用体能训练和 HIIT 计划),或灵活性/柔韧性训练(请使用灵活性训练计划)。
youtube-script-writer
Writes retention-engineered long-form YouTube scripts on a hook/body/payoff architecture - a first-30-seconds hook that survives the retention cliff, a beat-sheet body with mini-hooks and bridges, timed pattern interrupts, and a payoff that over-delivers - with B-roll and editing cues marked inline. Use when someone says "script my next video", "my retention graph dies at the start", "tighten this draft", or "outline a video on X". Do NOT use for the 3-second opener of TikTok, Reels, or Shorts - use video-hook-writer instead; do NOT use for spoken voiceover synced to on-screen tutorial actions - use narration-script instead; do NOT use for a sales demo built on a buyer's discovery notes - use demo-script instead; do NOT use to design the thumbnail and title - use thumbnail-concept instead.
win-back-campaign
Designs segmented win-back email sequences for dormant users - dormancy tiers, a three-beat sequence with a single proportional incentive, and a suppression rule - and measures success by re-activation, not opens. Use when someone says "our users went quiet", "design a win-back campaign", "how do I re-engage lapsed customers", "should we email people who haven't logged in for months", or lifecycle messaging has stopped landing with a lapsed segment. Do NOT use for recovering an unfinished checkout - use abandoned-cart-sequence instead. Do NOT use for diagnosing and fixing why active customers cancel - use churn-reduction instead. Do NOT use for building always-on onboarding or nurture flows - use email-drip-builder instead.
wikipedia-style
Writes neutral, verifiable, encyclopedic prose following Wikipedia's core content policies and manual of style - NPOV, inline citations, notability-backed claims, and a strict ban on promotional language. Use when someone asks "write this like a Wikipedia article", "draft a Wikipedia page for this company or person", "make this neutral and encyclopedic", or "why does my article draft keep getting rejected". Do NOT use for persuasive or opinion writing - use op-ed-writer instead; for thesis-driven academic papers, use academic-essay; for verifying claims in existing text, use fact-checker.
whitepapers
Structures and writes authoritative B2B whitepapers - a standalone executive summary, a data-sized problem statement, methodology, evidence-driven findings, recommendations, and a soft call to action - flagging every claim that needs a real citation. Use when a marketer asks "write a whitepaper on this topic", "turn our research into a lead-gen asset", "make this credible enough for executives", or a draft reads like a product pitch instead of analysis. Do NOT use for customer-story-driven proof - use case-study-builder instead; for policy audiences, use policy-brief.
white-space-analysis
Finds unmet market gaps by ranking jobs-to-be-done on importance versus satisfaction, overlaying them against current solutions and workarounds, and validating that each gap is real, winnable, and worth winning. Use when someone asks "where are the gaps in this market", "what's underserved here", "where should we play next", or is hunting for product, feature, or market-entry opportunities. Do NOT use for profiling competitors and building battle cards - use competitive-intelligence instead; for putting a dollar figure on an identified opportunity - use market-sizing instead; for extracting jobs-to-be-done from raw customer interviews - use jtbd-extractor instead.