test-driven-development
PanPanFR/oh-my-openkilo/skills/test-driven-development/SKILL.md
Use when implementing any feature or bugfix, before writing implementation code
Skill8 starsChanged 37 days ago
What's in it
- Test-Driven Development (TDD)
- The Iron Law
- When to Use
- Red-Green-Refactor
- RED - Write Failing Test
- Verify RED - Watch It Fail
- GREEN - Minimal Code
- Verify GREEN - Watch It Pass
- REFACTOR - Clean Up
- Repeat
- Good Tests
- Verification Checklist
- Debugging Integration
- When Stuck
- Final Rule
---
name: test-driven-development
description: Use when implementing any feature or bugfix, before writing implementation code
---
# Test-Driven Development (TDD)
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.**
## 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
## 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 - see `references/rationalizations.md`.
## Red-Green-Refactor
```
RED: write failing test -> VERIFY it fails correctly -> GREEN: minimal code -> VERIFY passes -> REFACTOR: clean up, stay green -> repeat
```
### RED - Write Failing Test
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 now.
### REFACTOR - Clean Up
After green only:
- Remove duplication
- Improve names
- Extract helpers
Keep tests green. Don't add behavior.
### Repeat
Next failing test for next feature.
## Good Tests
| Quality | Good | Bad |
|---------|------|-----|
| **Minimal** | One thing. "and" in name? Split it. | `test('validates email and domain and whitespace')` |
| **Clear** | Name describes behavior | `test('test1')` |
| **Shows intent** | Demonstrates desired API | Obscures what code should do |
**When writing or changing any test, read [writing-good-tests.md](writing-good-tests.md)** for the rules that keep tests honest:
- Name the production change that would make the test fail — before writing it
- Assert on real behavior, never on mock behavior
- Keep test-only code in test utilities, out of production classes
- Understand a dependency's side effects before mocking it
## Verification Checklist
Before marking work complete:
- [ ] Every new function/method has a test
- [ ] Watched each test fail before implementing
- [ ] Each test failed for expected reason (feature missing, not typo)
- [ ] Wrote minimal code to pass each test
- [ ] All tests pass
- [ ] Output pristine (no errors, warnings)
- [ ] Tests use real code (mocks only if unavoidable)
- [ ] Edge cases and errors covered
Can't check all boxes? You skipped TDD. Start over.
## Debugging Integration
Bug found? Write failing test reproducing it. Follow TDD cycle. Test proves fix and prevents regression.
Never fix bugs without a test.
## When Stuck
| Problem | Solution |
|---------|----------|
| Don't know how to test | Write wished-for API. Write assertion first. Ask your human partner. |
| Test too complicated | Design too complicated. Simplify interface. |
| Must mock everything | Code too coupled. Use dependency injection. |
| Test setup huge | Extract helpers. Still complex? Simplify design. |
## Final Rule
```
Production code → test exists and failed first
Otherwise → not TDD
```
No exceptions without your human partner's permission.
Tempted to rationalize? Read `references/rationalizations.md` before proceeding.
More agent context in PanPanFR/oh-my-openkilo
54 other files this repository gives its agents.
AGENTS.md
Skill
- agentmemory-agentsskills/agentmemory-agents/SKILL.md
- agentmemory-architectureskills/agentmemory-architecture/SKILL.md
- agentmemory-configskills/agentmemory-config/SKILL.md
- agentmemory-hooksskills/agentmemory-hooks/SKILL.md
- agentmemory-mcp-toolsskills/agentmemory-mcp-tools/SKILL.md
- agentmemory-rest-apiskills/agentmemory-rest-api/SKILL.md
- agentmemoryskills/agentmemory/SKILL.md
- antislopskills/antislop/SKILL.md
- caveman-compressskills/caveman-compress/SKILL.md
- caveman-helpskills/caveman-help/SKILL.md
- cavemanskills/caveman/SKILL.md
- caveman-statsskills/caveman-stats/SKILL.md
- clean-codeskills/clean-code/SKILL.md
- cloudflareskills/cloudflare/SKILL.md
- codebase-designskills/codebase-design/SKILL.md
- code-reviewskills/code-review/SKILL.md
- commit-contextskills/commit-context/SKILL.md
- commit-historyskills/commit-history/SKILL.md
- delegationskills/delegation/SKILL.md
- documentationskills/documentation/SKILL.md
- forgetskills/forget/SKILL.md
- git-commitskills/git-commit/SKILL.md
- graphifyskills/graphify/SKILL.md
- grillingskills/grilling/SKILL.md
- handoff-compactskills/handoff-compact/SKILL.md
- handoffskills/handoff/SKILL.md
- i-have-adhdskills/i-have-adhd/SKILL.md
- impeccableskills/impeccable/SKILL.md
- jev-decisionskills/jev-decision/SKILL.md
- lessonskills/lesson/SKILL.md
- memory-disciplineskills/memory-discipline/SKILL.md
- plansskills/plans/SKILL.md
- playwright-cliskills/playwright-cli/SKILL.md
- ponytail-reviewskills/ponytail-review/SKILL.md
- pwa-developmentskills/pwa-development/SKILL.md
- recallskills/recall/SKILL.md
- recapskills/recap/SKILL.md
- rememberskills/remember/SKILL.md
- resolving-merge-conflictsskills/resolving-merge-conflicts/SKILL.md
- session-historyskills/session-history/SKILL.md
- shadcnskills/shadcn/SKILL.md
- systematic-debuggingskills/systematic-debugging/SKILL.md
- ui-designskills/ui-design/SKILL.md
- ui-ux-pro-maxskills/ui-ux-pro-max/SKILL.md
- vercel-reactskills/vercel-react/SKILL.md
- verification-before-completionskills/verification-before-completion/SKILL.md
- viteskills/vite/SKILL.md
- vitestskills/vitest/SKILL.md
- web-design-guidelinesskills/web-design-guidelines/SKILL.md
- web-perfskills/web-perf/SKILL.md
- write-agentmemory-skillskills/write-agentmemory-skill/SKILL.md
- writing-skillsskills/writing-skills/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool public_context_discussion, action report. How to connect one.

