
Test Driven Development
Enforce red-green-refactor so every feature and bugfix ships with a failing test written first and minimal code to pass.
Overview
Test-Driven Development is an agent skill most often used in Ship (also Build backend and frontend) that forces failing tests before minimal implementation via Red-Green-Refactor.
Install
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill test-driven-developmentWhat is this skill?
- Iron law: no production code without a failing test first—prior implementation must be deleted, not kept as reference
- Red-Green-Refactor cycle with explicit verify-red and verify-green gates before refactor
- Mandatory for new features, bug fixes, refactoring, and behavior changes; exceptions only for throwaway prototypes, gene
- Anti-rationalization guardrails when tempted to skip TDD just once
- Dot-graph workflow diagram for the full TDD cycle in SKILL.md
- Red-Green-Refactor 3-step cycle with explicit verify-fail and verify-pass gates
Adoption & trust: 959 installs on skills.sh; 40.1k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are about to implement or fix code without proof the change is testable, scoped, or regression-safe.
Who is it for?
Solo builders adding features, fixing bugs, or refactoring in a real repo who want agent-assisted coding without untested production edits.
Skip if: Throwaway prototypes, generated boilerplate you will not maintain, or pure configuration edits—SKILL.md says ask your human partner before skipping; do not use when you refuse to delete code written before tests.
When should I use this skill?
Use when implementing any feature or bugfix, before writing implementation code.
What do I get? / Deliverables
Each change starts from a verified failing test, minimal passing code, and optional refactor—so you know the test actually guards the behavior before you ship or open a PR.
- Failing test that proves the right behavior
- Minimal production code that passes the suite
- Refactored code while staying green
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
TDD is the canonical testing discipline you invoke while implementing and before merge-quality work, so it shelves under Ship → Testing even though coding happens in Build. The iron law and verify-fail steps are test-first verification workflows, not generic coding or review-only passes.
Where it fits
Add an API endpoint by defining the failing contract test, then implement only enough handler code to pass.
Change UI behavior by writing a component test that fails, then wire the minimal fix.
Fix a production bug by reproducing it in a failing test before touching application code.
Refactor messy modules after green tests prove behavior is locked before you ask for human review.
How it compares
Use instead of letting the agent draft implementation first and bolt on tests afterward.
Common Questions / FAQ
Who is test-driven-development for?
Solo and indie builders using AI coding agents who want every meaningful code change anchored to a failing test they watched fail correctly.
When should I use test-driven-development?
During Build when implementing features or backends, during Ship when fixing bugs or changing behavior before review, and whenever you refactor production code—not for one-off prototypes unless you explicitly agree to skip with your partner.
Is test-driven-development safe to install?
It is instructional workflow text with no mandated shell or network access; review the Security Audits panel on this Prism page before installing from the upstream skills.sh bundle.
SKILL.md
READMESKILL.md - Test Driven Development
# Test-Driven Development (TDD) ## Overview Write the test first. Watch it fail. Write minimal code to pass. **Core principle:** If you didn't watch the test fail, you don't know if it tests the right thing. **Violating the letter of the rules is violating the spirit of the rules.** ## When to Use **Always:** - New features - Bug fixes - Refactoring - Behavior changes **Exceptions (ask your human partner):** - Throwaway prototypes - Generated code - Configuration files Thinking "skip TDD just this once"? Stop. That's rationalization. ## The Iron Law ``` NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST ``` Write code before the test? Delete it. Start over. **No exceptions:** - Don't keep it as "reference" - Don't "adapt" it while writing tests - Don't look at it - Delete means delete Implement fresh from tests. Period. ## Red-Green-Refactor ```dot digraph tdd_cycle { rankdir=LR; red [label="RED\nWrite failing test", shape=box, style=filled, fillcolor="#ffcccc"]; verify_red [label="Verify fails\ncorrectly", shape=diamond]; green [label="GREEN\nMinimal code", shape=box, style=filled, fillcolor="#ccffcc"]; verify_green [label="Verify passes\nAll green", shape=diamond]; refactor [label="REFACTOR\nClean up", shape=box, style=filled, fillcolor="#ccccff"]; next [label="Next", shape=ellipse]; red -> verify_red; verify_red -> green [label="yes"]; verify_red -> red [label="wrong\nfailure"]; green -> verify_green; verify_green -> refactor [label="yes"]; verify_green -> green [label="no"]; refactor -> verify_green [label="stay\ngreen"]; verify_green -> next; next -> red; } ``` ### RED - Write Failing Test Write one minimal test showing what should happen. <Good> ```typescript test('retries failed operations 3 times', async () => { let attempts = 0; const operation = () => { attempts++; if (attempts < 3) throw new Error('fail'); return 'success'; }; const result = await retryOperation(operation); expect(result).toBe('success'); expect(attempts).toBe(3); }); ``` Clear name, tests real behavior, one thing </Good> <Bad> ```typescript test('retry works', async () => { const mock = jest.fn() .mockRejectedValueOnce(new Error()) .mockRejectedValueOnce(new Error()) .mockResolvedValueOnce('success'); await retryOperation(mock); expect(mock).toHaveBeenCalledTimes(3); }); ``` Vague name, tests mock not code </Bad> **Requirements:** - One behavior - Clear name - Real code (no mocks unless unavoidable) ### Verify RED - Watch It Fail **MANDATORY. Never skip.** ```bash npm test path/to/test.test.ts ``` Confirm: - Test fails (not errors) - Failure message is expected - Fails because feature missing (not typos) **Test passes?** You're testing existing behavior. Fix test. **Test errors?** Fix error, re-run until it fails correctly. ### GREEN - Minimal Code Write simplest code to pass the test. <Good> ```typescript async function retryOperation<T>(fn: () => Promise<T>): Promise<T> { for (let i = 0; i < 3; i++) { try { return await fn(); } catch (e) { if (i === 2) throw e; } } throw new Error('unreachable'); } ``` Just enough to pass </Good> <Bad> ```typescript async function retryOperation<T>( fn: () => Promise<T>, options?: { maxRetries?: number; backoff?: 'linear' | 'exponential'; onRetry?: (attempt: number) => void; } ): Promise<T> { // YAGNI } ``` Over-engineered </Bad> Don't add features, refactor other code, or "improve" beyond the test. ### Verify GREEN - Watch It Pass **MANDATORY.** ```bash npm test path/to/test.test.ts ``` Confirm: - Test passes - Other tests still pass - Output pristine (no errors, warnings) **Test fails?** Fix code, not test. **Other tests fail?** Fix no