mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-15 02:50:53 +01:00
Twelve prose violations to zero. Eight files split into per-topic subdirectories with the original left as an index; both SKILL.md files keep their frontmatter so discovery still works, with detail moved to references/. Deleted docs/cleanup-2026-05/ (7 files) and linux_configuration/docs/ VERIFICATION.md on the user's ruling: unreferenced records of finished work whose rules are now enforced by the polling, shellcheck and shfmt hooks. PACMAN_WRAPPER_SECURITY.md was split instead - unlike those, it documents live guarantees. Every split verified by a sorted diff against HEAD: zero content lines lost, only the new headings and index links added. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
136 lines
4.0 KiB
Markdown
136 lines
4.0 KiB
Markdown
---
|
|
name: test-driven-development
|
|
description: Drives development with tests. Use when implementing any logic, fixing any bug, or changing any behavior. Use when you need to prove that code works, when a bug report arrives, or when you're about to modify existing functionality.
|
|
---
|
|
|
|
# Test-Driven Development
|
|
|
|
## Overview
|
|
|
|
Write a failing test before writing the code that makes it pass. For bug fixes, reproduce the bug with a test before attempting a fix. Tests are proof — "seems right" is not done. A codebase with good tests is an AI agent's superpower; a codebase without tests is a liability.
|
|
|
|
## When to Use
|
|
|
|
- Implementing any new logic or behavior
|
|
- Fixing any bug (the Prove-It Pattern)
|
|
- Modifying existing functionality
|
|
- Adding edge case handling
|
|
- Any change that could break existing behavior
|
|
|
|
**When NOT to use:** Pure configuration changes, documentation updates, or static content changes that have no behavioral impact.
|
|
|
|
**Related:** For browser-based changes, combine TDD with runtime verification using Chrome DevTools MCP — see the Browser Testing section below.
|
|
|
|
## The TDD Cycle
|
|
|
|
```
|
|
RED GREEN REFACTOR
|
|
Write a test Write minimal code Clean up the
|
|
that fails ──→ to make it pass ──→ implementation ──→ (repeat)
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
Test FAILS Test PASSES Tests still PASS
|
|
```
|
|
|
|
### Step 1: RED — Write a Failing Test
|
|
|
|
Write the test first. It must fail. A test that passes immediately proves nothing.
|
|
|
|
```typescript
|
|
// RED: This test fails because createTask doesn't exist yet
|
|
describe("TaskService", () => {
|
|
it("creates a task with title and default status", async () => {
|
|
const task = await taskService.createTask({ title: "Buy groceries" });
|
|
|
|
expect(task.id).toBeDefined();
|
|
expect(task.title).toBe("Buy groceries");
|
|
expect(task.status).toBe("pending");
|
|
expect(task.createdAt).toBeInstanceOf(Date);
|
|
});
|
|
});
|
|
```
|
|
|
|
### Step 2: GREEN — Make It Pass
|
|
|
|
Write the minimum code to make the test pass. Don't over-engineer:
|
|
|
|
```typescript
|
|
// GREEN: Minimal implementation
|
|
export async function createTask(input: { title: string }): Promise<Task> {
|
|
const task = {
|
|
id: generateId(),
|
|
title: input.title,
|
|
status: "pending" as const,
|
|
createdAt: new Date(),
|
|
};
|
|
await db.tasks.insert(task);
|
|
return task;
|
|
}
|
|
```
|
|
|
|
### Step 3: REFACTOR — Clean Up
|
|
|
|
With tests green, improve the code without changing behavior:
|
|
|
|
- Extract shared logic
|
|
- Improve naming
|
|
- Remove duplication
|
|
- Optimize if necessary
|
|
|
|
Run tests after every refactor step to confirm nothing broke.
|
|
|
|
## The Prove-It Pattern (Bug Fixes)
|
|
|
|
When a bug is reported, **do not start by trying to fix it.** Start by writing a test that reproduces it.
|
|
|
|
```
|
|
Bug report arrives
|
|
│
|
|
▼
|
|
Write a test that demonstrates the bug
|
|
│
|
|
▼
|
|
Test FAILS (confirming the bug exists)
|
|
│
|
|
▼
|
|
Implement the fix
|
|
│
|
|
▼
|
|
Test PASSES (proving the fix works)
|
|
│
|
|
▼
|
|
Run full test suite (no regressions)
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
// Bug: "Completing a task doesn't update the completedAt timestamp"
|
|
|
|
// Step 1: Write the reproduction test (it should FAIL)
|
|
it("sets completedAt when task is completed", async () => {
|
|
const task = await taskService.createTask({ title: "Test" });
|
|
const completed = await taskService.completeTask(task.id);
|
|
|
|
expect(completed.status).toBe("completed");
|
|
expect(completed.completedAt).toBeInstanceOf(Date); // This fails → bug confirmed
|
|
});
|
|
|
|
// Step 2: Fix the bug
|
|
export async function completeTask(id: string): Promise<Task> {
|
|
return db.tasks.update(id, {
|
|
status: "completed",
|
|
completedAt: new Date(), // This was missing
|
|
});
|
|
}
|
|
|
|
// Step 3: Test passes → bug fixed, regression guarded
|
|
```
|
|
|
|
## Further reading
|
|
|
|
Split out to keep this file under the 250-line cap.
|
|
|
|
- [The test pyramid and writing good tests](references/test-pyramid-and-good-tests.md)
|
|
- [Anti-patterns, browser testing and verification](references/anti-patterns-and-browser.md)
|