
tdd
Test-driven development, from unit to end-to-end tests. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration or end-to-end tests (Playwright, Cypress). Don't use to backfill tests on existing code (/refactor) or diagnose an unknown bug (/debug).
- Installs
- 48
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/helderberto/agent-skills --skill tdd- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads tdd automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Test-Driven Development
Philosophy
Core principle: Tests should verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't.
Good tests are integration-style: they exercise real code paths through public APIs. They describe what the system does, not how it does it. A good test reads like a specification - "user can checkout with valid cart" tells you exactly what capability exists. These tests survive refactors because they don't care about internal structure.
Bad tests are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior.
See tests.md for examples, mocking.md for mocking guidelines, and ui-tests.md for end-to-end tests of user flows.
Anti-Pattern: Horizontal Slices
DO NOT write all tests first, then all implementation. This is "horizontal slicing" - treating RED as "write all tests" and GREEN as "write all code."
This produces crap tests:
- Tests written in bulk test imagined behavior, not actual behavior
- You end up testing the shape of things (data structures, function signatures) rather than user-facing behavior
- Tests become insensitive to real changes - they pass when behavior breaks, fail when behavior is fine
- You outrun your headlights, committing to test structure before understanding the implementation
Correct approach: Vertical slices via tracer bullets. One test → one implementation → repeat. Each test responds to what you learned from the previous cycle. Because you just wrote the code, you know exactly what behavior matters and how to verify it.
WRONG (horizontal):
RED: test1, test2, test3, test4, test5
GREEN: impl1, impl2, impl3, impl4, impl5
RIGHT (vertical):
RED→GREEN: test1→impl1
RED→GREEN: test2→impl2
RED→GREEN: test3→impl3
...
Anti-Pattern: Tautological Tests
The assertion recomputes the expected value the same way the code does — expect(add(a, b)).toBe(a + b), a snapshot derived by hand via the same logic, a constant asserted equal to itself. The test passes by construction and can never disagree with the code.
Expected values must come from an independent source of truth: a known-good literal, a worked example, the spec. See tests.md for an example.
Workflow
0. Discover the stack
The TDD cycle is universal; the commands are not. Before the first test, discover how this repository tests and use its commands for every RED and GREEN:
- Build system:
package.json,pyproject.toml,go.mod,Cargo.toml,Makefile - Checked-in wrappers first:
./gradlew,./mvnw,make test, repo scripts — never a globally installed tool the repo doesn't use - The focused-single-test command vs the full-suite command — run focused during the loop, full suite once before completion
- Where tests live, how they're named, what patterns neighboring tests follow
- CI workflows show the commands that actually gate merges
Never assume npm test.
1. Planning
When exploring the codebase, read GLOSSARY.md if it exists (else a legacy CONTEXT.md; GLOSSARY-MAP.md points to the right one in a multi-context repo) so that test names and interface vocabulary match the project's domain language, and respect ADRs in the area you're touching.
A seam is the public boundary you test at: the interface where you observe behavior without reaching inside. Before writing any test, write down the seams under test, one line each on what a test there catches and what it misses, and confirm them with the user:
Ask: "What's the public interface, and which seams should we test?"
No test is written at an unconfirmed seam.
Before writing any code:
- Confirm the seams under test with the user
- Confirm with user which behaviors to test (prioritize)
- Identify opportunities for deep modules (small interface, deep implementation) — call the Skill tool with
codebase-designfor the vocabulary and the testability checks - List the behaviors to test (not implementation steps)
- Get user approval on the plan
You can't test everything. Agreeing the seams up front is how testing effort lands on critical paths and complex logic, not every possible edge case.
2. Tracer Bullet
Write ONE test that confirms ONE thing about the system:
RED: Write test for first behavior → test fails
GREEN: Write minimal code to pass → test passes
This is your tracer bullet - proves the path works end-to-end.
3. Incremental Loop
For each remaining behavior:
RED: Write next test → fails
GREEN: Minimal code to pass → passes
Rules:
- One test at a time
- Only enough code to pass current test
- Don't anticipate future tests
- Keep tests focused on observable behavior
4. Refactor
Only once GREEN — never while RED. Extract duplication, deepen modules (call the Skill tool with codebase-design for the vocabulary), and ask what the new code reveals about existing code. Run tests after each step.
FAQ
What does the tdd skill do?
Test-driven development, from unit to end-to-end tests. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration or end-to-end tests (Playwright, Cypress). Don't use to backfill tests on existing code (/refactor) or diagnose an unknown bug (/debug).
How do I install tdd?
Run npx skills add https://github.com/helderberto/agent-skills --skill tdd in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/tdd/ (personal) or .claude/skills/tdd/ (project).
Which AI agents can use tdd?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is tdd safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains tdd?
It is published by helderberto in helderberto/agent-skills. It has 48 recorded installs.
More from helderberto/agent-skills
code-review
helderberto/agent-skills
Correctness lens for a PR or diff, used by build and review — bugs, security, performance, and code quality. Use when asked to review a PR or give pull request feedback, even when the diff is pasted inline. Don't use for local uncommitted changes, creating PRs, or merging.
explain-code
helderberto/agent-skills
Explains code with visual diagrams and analogies. Use when explaining how code works, walking through a codebase area, or when the user asks "how does this work?" Don't use for modifying code, fixing bugs, generating new implementations, or multi-session concept learning (use /teach).
commit
helderberto/agent-skills
Group unstaged changes into atomic commits by concern, matching repository style. Use when asked to "commit", "create a commit", or "commit changes". Don't use for pushing or pull requests (/to-pr).
lint
helderberto/agent-skills
Run linting and formatting checks. Use when user asks to "run linter", "/lint", "check linting", "fix lint errors", or requests code linting/formatting. Don't use for the full format/type/test pass (use /validate-code) or for installing commit-time hooks (use /setup-pre-commit).
refactor-plan
helderberto/agent-skills
Create structured refactoring plans. Use when user wants to plan a refactor, needs a refactoring strategy, or mentions breaking down large changes into small commits. Don't use for implementing code changes directly, small one-line fixes, or renaming a single variable.
Popular testing & qa skills
tdd
mattpocock/skills
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
grilling
mattpocock/skills
Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
migrate-to-shoehorn
mattpocock/skills
Migrate test files from as type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace as in tests, or needs partial test data.
run-train
lllllllama/rigorpilot-skills
Rigor Train skill for deep learning research repositories. Use when a documented or selected training command should be run conservatively for startup verification, short-run verification, full kickoff, or resume, with command, config, seed, log, checkpoint, status, and metric evidence written to standardized trainoutputs/. Do not use for environment setup, exploratory sweeps, speculative idea implementation, or end-to-end orchestration.
test-driven-development
obra/superpowers
Use when implementing any feature or bugfix, before writing implementation code
finishing-a-development-branch
obra/superpowers
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work