Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:03:43 +08:00
commit 2d7bed1e9d
8 changed files with 1725 additions and 0 deletions

274
commands/kb-red.md Normal file
View File

@@ -0,0 +1,274 @@
---
description: 寫下一個測試Red 階段)。一次只寫一個最小的測試,讓它失敗。
---
# TDD Red - 寫下一個測試Red
寫下一個小測試,看它失敗。
**【功能名】**{{feature_name}}
## Kent Beck 的 Red 階段理念
> "寫一個小測試。讓它失敗。"
### 一次一個測試的原則
**為什麼一次只寫一個?**
- 保持專注
- 快速反饋
- 小步前進
- 容易回退
### 如何選擇下一個測試?
Kent Beck 的建議:
1. **從 To-Do List 選**(心理 To-Do不是文件
- 腦中想到什麼測試,記下來
- 選最簡單的開始
2. **從上一個測試的經驗**
- 上一個測試通過了,下一步自然浮現
- "如果這樣,那會怎樣?"
3. **三角測量**
- 如果不確定實作,寫第二個類似的測試
- 從多個角度逼近正確實作
## 寫測試的步驟
### 1. 更新 journey.md
```markdown
### 第 N 輪 - {日期時間}
#### 🤔 想法
{為什麼要寫這個測試?從上一輪學到什麼?}
#### 🔴 Red - 寫測試
測試名稱:{測試名稱}
```
### 2. 寫測試程式碼
**測試結構Given-When-Then**
```javascript
test('簡短描述測試意圖', () => {
// Given - 準備
// 【準備】:{為什麼需要這些資料?}
const input = testData;
// When - 執行
// 【執行】:{測試什麼行為?}
const result = functionUnderTest(input);
// Then - 驗證
// 【驗證】:{為什麼期待這個結果?}
expect(result).toBe(expected);
});
```
### 3. 執行測試,確認失敗
```bash
npm test
```
**必須看到失敗!**
- 如果沒失敗,測試可能有問題
- 失敗訊息要清楚
### 4. 記錄失敗訊息
在 journey.md 中:
```markdown
#### 失敗訊息
```
{實際的錯誤訊息}
```
#### 📝 下一步
執行 /kb-green 讓測試通過
```
## 測試大小的藝術
### 測試要多小?
Kent Beck 的答案:**取決於你的信心**
**信心低(不確定)**
- 寫更小的測試
- 更頻繁的反饋
**信心高(很確定)**
- 可以寫大一點的測試
- 跨越明顯的步驟
### 範例:小測試 vs 大測試
**小測試(信心低時)**
```javascript
// 第 1 個測試:最基本的
test('5 元乘以 2 等於 10 元', () => {
const five = new Dollar(5);
const product = five.times(2);
expect(product.amount).toBe(10);
});
// 第 2 個測試:檢查副作用
test('乘法不改變原物件', () => {
const five = new Dollar(5);
five.times(2);
expect(five.amount).toBe(5); // 原值不變
});
```
**大測試(信心高時)**
```javascript
// 直接測試完整行為
test('Dollar 乘法運算', () => {
const five = new Dollar(5);
const ten = five.times(2);
expect(ten.amount).toBe(10);
expect(five.amount).toBe(5); // 也檢查副作用
});
```
## 三角測量的時機
當你不確定實作時,用三角測量:
```javascript
// 第 1 個測試
test('1 + 1 = 2', () => {
expect(add(1, 1)).toBe(2);
});
// 最簡單的假實作
function add(a, b) {
return 2; // 硬編碼
}
// 第 2 個測試(三角測量)
test('2 + 3 = 5', () => {
expect(add(2, 3)).toBe(5);
});
// 現在必須寫真正的實作
function add(a, b) {
return a + b;
}
```
## To-Do List 技巧
Kent Beck 建議在測試程式碼中寫註解:
```javascript
describe('Dollar', () => {
// TODO: 測試加法
// TODO: 測試負數
// TODO: 測試相等性
test('乘法', () => {
// 目前的測試
});
});
```
或在 journey.md 中:
```markdown
## 心理 To-Do List
- [x] 基本乘法
- [ ] 乘法副作用
- [ ] 加法運算
- [ ] 負數處理
```
## 常見問題
### Q: 要不要測試所有邊界情況?
Kent Beck**不用一開始就全測**
- 先從明顯的案例開始
- 邊界情況在需要時再加入
- 讓測試自然演進
### Q: 測試名稱要多詳細?
Kent Beck**描述意圖,不是實作**
```javascript
// ✅ 好的測試名稱
test('購物車加入商品後,總價增加')
// ❌ 不好的測試名稱
test('testAddItem')
```
### Q: 要寫測試到什麼程度?
Kent Beck**寫到你有信心為止**
- 如果還不確定,再寫一個測試
- 如果已經確定,可以跳到實作
## 範例Money 第一個測試
```javascript
// __tests__/money.test.js
describe('Dollar', () => {
test('乘法運算', () => {
// 【準備】:建立 5 元的 Dollar 物件
const five = new Dollar(5);
// 【執行】:乘以 2
const product = five.times(2);
// 【驗證】:結果應該是 10 元
expect(product.amount).toBe(10);
});
});
```
執行測試:
```bash
npm test
# 結果:失敗!
# Error: Dollar is not defined
```
在 journey.md 記錄:
```markdown
### 第 1 輪
#### 🔴 Red - 寫測試
測試名稱Dollar 乘法運算
#### 失敗訊息
```
Error: Dollar is not defined
```
#### 📝 下一步
執行 /kb-green 建立 Dollar 類別
```
## 下一步
測試寫好且失敗了?執行:
```
/kb-green
```
用最簡單的方式讓測試通過!
## 記住
> "測試不是目的,而是思考的工具。"
> "失敗的測試是進步的開始。"
> "一次一小步,但要持續前進。"