tdd
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
TDD Test-Driven Development Skill — Write Tests Worth Keeping with the Red-Green Cycle
Skill Overview
The TDD skill guides the AI assistant through the red → green cycle of test-driven development: first write a failing test, then write the minimum code needed to make it pass. Tests are written only at seams agreed upon in advance.
Use Cases
-
Developing a new feature and wanting to write tests first: When you want to build a feature using a test-driven approach instead of writing the code first and adding tests afterward, this skill proceeds one seam, one test, and one minimal implementation at a time.
-
Fixing a bug by first writing a reproduction test: Pin down the issue with a test that reliably reproduces the defect, then modify the code until the test turns green. This prevents situations where the fix seems successful but you do not know whether it broke anything else.
-
Needing integration tests rather than only unit tests: The skill also covers how to write integration tests. Tests are placed at the public-interface layer to verify real behavior rather than internal structure.
Core Features
-
Red-green cycle execution: Strictly red before green—write a failing test first, then write only enough code to make it pass. The skill does not implement future functionality in advance or add speculative features along the way. Each cycle advances only one vertical slice (tracer bullet), and the next step is determined by what was learned in the previous round.
-
Seam agreement: Before writing any tests, first list the seams to be tested and confirm them with you. A seam is the public boundary at which behavior is observed. Tests live only at the seam and never reach into the internals. Since it is impossible to test everything, agreeing on seams in advance ensures testing effort is focused on critical paths and complex logic rather than every edge case. If the shape of your interface is still undecided—how deeply to structure the module, where to place the seam, or what the interface should expose—the skill will guide you to align with relevant terminology from
codebase-design. -
Anti-pattern safeguards: The skill explicitly identifies and actively avoids three categories of testing anti-patterns:
- Implementation coupling: Mocking internal collaborators, testing private methods, or bypassing the interface to query the database as a form of “side-channel” verification. The telltale sign is that the tests fail after a refactor even though behavior remains unchanged.
- Circular reasoning: Recomputing expected values in the same way as the code under test—for example,
expect(add(a, b)).toBe(a + b), or manually creating a snapshot based on the same logic as the implementation. Such tests are constructed to pass and can never disagree with the code. Expected values must come from an independent source of truth: known-correct literals, manually calculated examples, or a specification. - Horizontal slicing: Writing all tests in one go before implementing anything. Batch-written tests verify imagined behavior, test shape rather than user-observable behavior, and lock in the test structure before the implementation is understood.
Common Questions
Does TDD always require writing tests first? Does writing tests after the code count?
No. The core rule of this skill is red before green: the failing test must exist before the code that makes it pass. Writing tests after the implementation means you already know the answer, making it difficult to verify that the test itself can genuinely fail.
The cycle also does not allow writing all the tests at once—that is the “horizontal slicing” anti-pattern. It verifies imagined behavior, locks in the test structure prematurely, and proceeds through vertical slices instead: one seam → one test → one minimal implementation. Each test is like a tracer bullet, and the next step is determined by what was learned in the previous round. Refactoring is likewise not part of this cycle; it belongs to the review phase, handled by the code-review skill.
What is a test seam? Why agree on it in advance?
A seam is the public boundary you want to test—the layer at which behavior is observed without reaching into the internals. The skill requires writing tests only at seams agreed upon in advance; no tests are written at unconfirmed seams. The reason is that testing resources are limited. Aligning on seams beforehand ensures effort is spent on critical paths and complex logic rather than spread across every edge case.
If the shape of your interface has not yet been determined—how deeply to structure the module, where to place the seam, or what the interface should expose—the skill will guide you to align with concepts such as modules, interfaces, depth, and adapters from codebase-design.
Why do my tests fail whenever I refactor?
The most likely cause is implementation coupling. If a test mocks internal collaborators, directly tests private methods, or bypasses the interface and uses a side channel—such as querying the database directly—to verify behavior, then it is testing structure rather than behavior. When the structure changes, the behavior may remain the same, but the test still turns red. The rule of thumb is simple: if behavior remains unchanged after a refactor but the test fails, the test is written at the wrong layer.