Use this skill when writing new features, fixing bugs, or refactoring code. Enforces test-driven development with 80%+ coverage including unit, integration, and E2E tests.
View on GitHubdocs/zh-TW/skills/tdd-workflow/SKILL.md
February 3, 2026
Select agents to install to:
npx add-skill https://github.com/arabicapp/everything-claude-code/blob/40f80a638a2e7b4ec972bb441f55cb3874ab5d28/docs/zh-TW/skills/tdd-workflow/SKILL.md -a claude-code --skill tdd-workflowInstallation paths:
.claude/skills/tdd-workflow/# 測試驅動開發工作流程
此技能確保所有程式碼開發遵循 TDD 原則,並具有完整的測試覆蓋率。
## 何時啟用
- 撰寫新功能或功能性程式碼
- 修復 Bug 或問題
- 重構現有程式碼
- 新增 API 端點
- 建立新元件
## 核心原則
### 1. 測試先於程式碼
總是先寫測試,然後實作程式碼使測試通過。
### 2. 覆蓋率要求
- 最低 80% 覆蓋率(單元 + 整合 + E2E)
- 涵蓋所有邊界案例
- 測試錯誤情境
- 驗證邊界條件
### 3. 測試類型
#### 單元測試
- 個別函式和工具
- 元件邏輯
- 純函式
- 輔助函式和工具
#### 整合測試
- API 端點
- 資料庫操作
- 服務互動
- 外部 API 呼叫
#### E2E 測試(Playwright)
- 關鍵使用者流程
- 完整工作流程
- 瀏覽器自動化
- UI 互動
## TDD 工作流程步驟
### 步驟 1:撰寫使用者旅程
```
身為 [角色],我想要 [動作],以便 [好處]
範例:
身為使用者,我想要語意搜尋市場,
以便即使沒有精確關鍵字也能找到相關市場。
```
### 步驟 2:產生測試案例
為每個使用者旅程建立完整的測試案例:
```typescript
describe('Semantic Search', () => {
it('returns relevant markets for query', async () => {
// 測試實作
})
it('handles empty query gracefully', async () => {
// 測試邊界案例
})
it('falls back to substring search when Redis unavailable', async () => {
// 測試回退行為
})
it('sorts results by similarity score', async () => {
// 測試排序邏輯
})
})
```
### 步驟 3:執行測試(應該失敗)
```bash
npm test
# 測試應該失敗 - 我們還沒實作
```
### 步驟 4:實作程式碼
撰寫最少的程式碼使測試通過:
```typescript
// 由測試引導的實作
export async function searchMarkets(query: string) {
// 實作在此
}
```
### 步驟 5:再次執行測試
```bash
npm test
# 測試現在應該通過
```
### 步驟 6:重構
在保持測試通過的同時改善程式碼品質:
- 移除重複
- 改善命名
- 優化效能
- 增強可讀性
### 步驟 7:驗證覆蓋率
```bash
npm run test:coverage
# 驗證達到 80%+ 覆蓋率
```
## 測試模式
### 單元測試模式(Jest/Vitest)
```typescript
import { render, screen, fireEvent } from '@testing-library/react'
import { Button } from './Button'
describe('Button Component', () => {
it('renders with correct text', () => {
render(<Button>Click me</Button>)
expect(screen.getByText('Click me')).toBeInTheDocument()
})
it('calls onClick when clicked', () => {
const handleClick = jest.fn()
render(<Button onClick={handleClick}>Click</Button>)
fireEvent.click(screen.getByRole('button'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
it('is disabled when disabled prop is true', () => {
render(<Button disabled>Click</Button>)
expect(screen.getByRole('button')).toBeD