test-driven-development
Use when implementing any feature or bugfix, before writing implementation code
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Use when implementing any feature or bugfix, before writing implementation code
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.
Use when an HTML UI beats terminal text — collecting structured answers (decision trees, multi-select, code/SQL fields), showing visual comparisons or mockups, running interactive demos, or presenting decisions for approval. A local browser companion renders markdown+YAML screens and streams the user's answers back. Use when: many questions at once, layout/visual choices, mockup or diagram feedback, config wizard, demo review, approve/revise decisions. Skip: a single quick question (use AskUserQuestion or plain text).
Use when you have a spec or requirements for a multi-step task, before touching code
Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions
Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies
Use when you have a written implementation plan to execute in a separate session with review checkpoints
| name | test-driven-development |
| description | Use when implementing any feature or bugfix, before writing implementation code |
先寫測。觀其敗。後寫最簡碼以過。
核心原則: 未觀測敗,則不知其測真物否。
違其字即違其意。
常:
例外(問 your human partner):
思「僅此一次跳 TDD」? 止。此即託辭。
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
測前寫碼? 刪之。重起。
無例外:
從測重作。止。
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;
}
寫一最小測示其應行之事。
```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); });
清名,測真行為,一物
</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);
});
模糊名,測 mock 非 code
所需:
必行。勿跳。
npm test path/to/test.test.ts
確:
測過? 汝測既有行為。修測。
測錯? 修錯,再跑至正確敗。
寫最簡碼以過測。
```typescript async function retryOperation(fn: () => Promise): Promise { for (let i = 0; i < 3; i++) { try { return await fn(); } catch (e) { if (i === 2) throw e; } } throw new Error('unreachable'); } ``` 剛好過 ```typescript async function retryOperation( fn: () => Promise, options?: { maxRetries?: number; backoff?: 'linear' | 'exponential'; onRetry?: (attempt: number) => void; } ): Promise { // YAGNI } ``` 過度工程勿加功、勿重構他碼、勿超測「改良」。
必行。
npm test path/to/test.test.ts
確:
測敗? 修碼,非測。
他測敗? 立修。
綠後方可:
保測綠。勿加行為。
次功之次測敗。
| Quality | Good | Bad |
|---|---|---|
| Minimal | 一物。名含「and」? 拆之。 | test('validates email and domain and whitespace') |
| Clear | 名述行為 | test('test1') |
| Shows intent | 示期望 API | 晦其應行 |
「吾測後以驗碼效」
碼後之測立即過。立即過無證:
測先強汝觀測敗,證其真測某事。
「吾已手測所有邊界」
手測 ad-hoc。汝自以為全測,然:
自動測系統化。每次同樣執行。
「刪 X 小時之工浪費」
沉沒成本誤。時已逝。汝今之擇:
「浪費」乃留不可信之碼。無真測之碼即技債。
「TDD 教條,務實意調整」
TDD 方為務實:
「務實」捷徑 = prod debug = 更慢。
「測後得同目標——乃意不儀」
非也。測後答「此作何事?」 測先答「此當作何事?」
測後偏於實作。汝測所建,非所需。汝驗記得之邊界,非探得之。
測先強邊界探於實作前。測後驗汝記得(汝未記得)。
30 分之測後 ≠ TDD。得 coverage,失測真作之證。
| Excuse | Reality |
|---|---|
| 「太簡無需測」 | 簡碼亦斷。測耗 30 秒。 |
| 「吾後測」 | 立即過之測無證。 |
| 「測後得同目標」 | 測後=「此作何事?」 測先=「此當作何事?」 |
| 「已手測」 | Ad-hoc ≠ 系統化。無記、不可重跑。 |
| 「刪 X 小時浪費」 | 沉沒成本誤。留不可信之碼即技債。 |
| 「留為參考,測先寫」 | 汝必改用。即測後。刪即刪。 |
| 「須先探」 | 可。棄探,以 TDD 始。 |
| 「難測 = 設計不明」 | 聽測。難測 = 難用。 |
| 「TDD 緩吾」 | TDD 速於 debug。務實即測先。 |
| 「手測快」 | 手測不證邊界。每改皆重測。 |
| 「既碼無測」 | 汝改之。為既碼加測。 |
皆意:刪碼。以 TDD 重起。
Bug: 空 email 受
RED
test('rejects empty email', async () => {
const result = await submitForm({ email: '' });
expect(result.error).toBe('Email required');
});
Verify RED
$ npm test
FAIL: expected 'Email required', got undefined
GREEN
function submitForm(data: FormData) {
if (!data.email?.trim()) {
return { error: 'Email required' };
}
// ...
}
Verify GREEN
$ npm test
PASS
REFACTOR 若需,抽多欄 validation。
標竟工前:
未能皆勾? 汝跳 TDD。重起。
| Problem | Solution |
|---|---|
| 不知如何測 | 寫願之 API。先寫 assertion。問 your human partner。 |
| 測過繁 | 設計過繁。簡其介面。 |
| 須 mock 所有 | 碼過耦。用 dependency injection。 |
| 測 setup 大 | 抽 helper。仍繁? 簡設計。 |
見 bug? 寫失敗測以復之。遵 TDD 環。測證修並防回歸。
勿修 bug 無測。
加 mock 或 test utility 時,讀 @testing-anti-patterns.md 以避常陷:
Production code → test exists and failed first
Otherwise → not TDD
無 your human partner 之許則無例外。