# /tdd — 測試驅動開發 (Test-Driven Development)

使用**測試驅動開發 (TDD)** 模式實作功能。在撰寫任何邏輯代碼之前，先撰寫失敗的測試。

## 流程

1. **規劃 (Plan)**：定義功能需求與介面。
2. **紅燈 (Red)**：撰寫一個會失敗的測試（因為實作尚未存在）。
3. **綠燈 (Green)**：撰寫最少量的實作程式碼以使測試通過。
4. **重構 (Refactor)**：清理程式碼同時保持測試通過。
5. **重複 (Repeat)**：進行下一個小型測試。

## 使用範例

```bash
/tdd 實作一個處理使用者註冊並驗證電子郵件的函式
/tdd 建立一個具有 push, pop 和 peek 功能的堆疊 (Stack) 資料結構
/tdd 為現有的 API 新增一個計算折扣的端點 (Endpoint)
```

## Go 語言範例流程

````markdown
## 步驟 1：定義需求
實作一個電子郵件驗證器，檢查是否為空且格式是否正確。

## 步驟 2：紅燈 — 撰寫失敗的測試
建立 `validator_test.go`:

```go
func TestValidateEmail(t *testing.T) {
    err := ValidateEmail("")
    if err == nil {
        t.Error("預期空字串會回報錯誤，但結果為 nil")
    }
}
```

## 步驟 3：綠燈 — 使測試通過
建立 `validator.go`:

```go
func ValidateEmail(email string) error {
    if email == "" {
        return errors.New("email cannot be empty")
    }
    return nil
}
```

## 步驟 4：重構
將錯誤定義為具名的常數。

```go
var (
    ErrEmailEmpty   = errors.New("email cannot be empty")
    ErrEmailInvalid = errors.New("email format is invalid")
)

func ValidateEmail(email string) error {
    if email == "" {
        return ErrEmailEmpty
    }
    if !emailRegex.MatchString(email) {
        return ErrEmailInvalid
    }
    return nil
}
```

## 步驟 5：執行測試 — 驗證通過
```bash
$ go test ./validator/...
PASS
ok      project/validator    0.003s
```

## 步驟 6：檢查覆蓋率
```bash
$ go test -cover ./validator/...
PASS
coverage: 100.0% of statements
```
````

## 測試模式

### 表格驅動測試 (Table-Driven Tests)
```go
tests := []struct {
    name     string
    input    InputType
    want     OutputType
    wantErr  bool
}{
    {"case 1", input1, want1, false},
    {"case 2", input2, want2, true},
}

for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
        got, err := Function(tt.input)
        // 斷言 (assertions)
    })
}
```

## 規則
- **測試先行**：絕對不在撰寫測試之前撰寫實作程式碼。
- **最小實作**：僅撰寫足以通過目前測試的程式碼。
- **持續驗證**：在每個步驟之後執行所有測試。
- **覆蓋率理想值**：目標為新程式碼達到 100% 覆蓋率。
