結論先講

AI 是優秀的測試起草者,但糟糕的測試決策者。 讓 AI 產生 boilerplate 測試、發現邊界案例、寫 snapshot 測試——這些它很擅長。但「這個功能該測什麼」、「這個 mock 的行為對不對」、「測試覆蓋的業務場景夠不夠」——這些判斷還是需要人。

2026 年的現狀:AI 可以把你寫測試的時間縮短 40-60%,但如果完全不看 AI 產生的測試就直接 commit,你最後會得到一堆 coverage 數字很漂亮但實際上什麼都沒驗證的測試。


AI 測試工具現況(2026)

Claude Code

Claude Code 的 /test 指令可以直接為指定的檔案或函式產生測試:

# 基本用法
claude /test src/services/order.ts
 
# 指定測試框架
claude /test src/services/order.ts --framework vitest
 
# 針對特定函式
claude /test src/utils/price.ts --function calculateDiscount

它也能從 PR diff 推斷該寫什麼測試:

# 根據你的改動建議測試
claude "幫我寫這次改動相關的測試" --diff

GitHub Copilot

Copilot 在 IDE 裡的 inline 測試建議已經相當成熟:

// 你寫了這個函式
function calculateShippingFee(weight: number, distance: number): number {
  if (weight <= 0) throw new Error('Weight must be positive');
  if (distance <= 0) throw new Error('Distance must be positive');
  const baseFee = 60;
  const weightFee = Math.ceil(weight / 5) * 10;
  const distanceFee = distance > 100 ? 50 : 0;
  return baseFee + weightFee + distanceFee;
}
 
// Copilot 會建議的測試(在測試檔案裡打 describe 就會觸發)
describe('calculateShippingFee', () => {
  it('should calculate base fee correctly', () => {
    expect(calculateShippingFee(1, 50)).toBe(70); // 60 + 10
  });
 
  it('should round up weight to nearest 5kg', () => {
    expect(calculateShippingFee(6, 50)).toBe(80); // 60 + 20
  });
 
  it('should add distance surcharge for >100km', () => {
    expect(calculateShippingFee(1, 150)).toBe(120); // 60 + 10 + 50
  });
 
  it('should throw on negative weight', () => {
    expect(() => calculateShippingFee(-1, 50)).toThrow('Weight must be positive');
  });
});

這種純計算邏輯的測試,AI 生成的品質通常不錯。


AI 測試生成的優缺點

AI 擅長的

場景AI 的表現為什麼
純函式測試優秀輸入輸出明確,容易推斷
邊界案例發現很好AI 會嘗試 null、0、負數、超大值
Boilerplate 測試優秀describe/it 結構、setup/teardown
Snapshot 測試很好只要呼叫函式然後 toMatchSnapshot
Error handling 測試不錯AI 會測所有 throw 路徑
API endpoint 測試不錯標準的 HTTP method + status code

AI 不擅長的

場景AI 的表現為什麼
業務邏輯驗證AI 不知道「VIP 打 8 折」的業務規則
Integration 情境不了解服務之間的互動
Mock 行為正確性AI 會 mock 到你想測的東西
測試策略決定不知道哪些場景重要
非功能需求效能、安全、併發場景

AI 生成測試的常見問題

問題 1:測試 implementation 而不是 behavior

// AI 常常生成這種測試
it('should call repository.save', async () => {
  const repo = { save: jest.fn() };
  const service = new OrderService(repo);
  await service.createOrder({ productId: 1, qty: 2 });
  expect(repo.save).toHaveBeenCalledWith(
    expect.objectContaining({ productId: 1, quantity: 2 })
  );
});

這個測試只驗證了「有沒有呼叫 save」,完全沒驗證「訂單建立的業務邏輯對不對」。如果你重構了 createOrder 的內部實作(例如改用 event-driven),測試就壞了,但功能其實沒壞。

該測的是行為:

it('should create order with correct total', async () => {
  const product = await ProductFactory.create({ price: 500 });
  const order = await orderService.createOrder({
    productId: product.id,
    qty: 2,
  });
  expect(order.total).toBe(1000);
  expect(order.status).toBe('pending');
});

問題 2:Over-mocking

AI 很喜歡 mock 東西,因為 mock 可以讓測試不依賴外部。但 mock 過度會讓你測的是「你的 mock」而不是「你的 code」:

// AI 生成的——mock 了所有東西
it('should process payment', async () => {
  const gateway = { charge: jest.fn().mockResolvedValue({ id: 'pay_123' }) };
  const notifier = { send: jest.fn() };
  const repo = { save: jest.fn() };
 
  const service = new PaymentService(gateway, notifier, repo);
  await service.processPayment(100);
 
  expect(gateway.charge).toHaveBeenCalledWith(100);
  expect(notifier.send).toHaveBeenCalled();
  expect(repo.save).toHaveBeenCalled();
});
// 這測了什麼?測了你 mock 的行為而已。

問題 3:測試描述跟實際測試不符

// AI 生成的
it('should handle concurrent orders correctly', async () => {
  const order = await createOrder({ productId: 1, qty: 1 });
  expect(order).toBeDefined();
});
// 名字寫「concurrent」,但根本沒有併發測試

實務工作流程:AI + 人類協作

推薦流程

Step 1: AI 生成初版測試
  └── 用 Claude Code /test 或 Copilot

Step 2: 人類審查
  ├── 刪掉測試 implementation 的測試
  ├── 修正 mock 策略(減少不必要的 mock)
  ├── 確認業務邏輯覆蓋率
  └── 補上 AI 想不到的場景

Step 3: 人類補寫關鍵測試
  ├── 核心業務邏輯
  ├── 跨服務互動
  └── Edge case(基於 domain knowledge)

Step 4: AI 輔助 refactor
  └── 「幫我把這 5 個測試的重複 setup 抽出來」

實際操作範例

# Step 1: 讓 Claude Code 生成初版
claude "幫 src/services/discount.ts 寫測試,用 vitest"
 
# Claude 會生成大約 10-15 個測試案例
# 大部分是計算邏輯和 error handling
 
# Step 2: 人類審查後,發現缺少
# - VIP 會員折扣疊加規則
# - 折扣碼過期處理
# - 同一訂單不能用兩張折扣碼
 
# Step 3: 人類補上業務邏輯測試
# Step 4: 讓 AI 幫忙重構測試結構
claude "把 discount.test.ts 的重複 setup 用 beforeEach 整理一下"

AI 作為測試 Reviewer

比起生成測試,AI 在 review 測試方面其實更有用:

# 讓 AI review 你的測試
claude "review 這個測試檔案,告訴我:
1. 有沒有漏掉的邊界案例
2. 有沒有測 implementation 而不是 behavior 的測試
3. mock 策略對不對
4. 測試命名清不清楚"

AI 在這方面的表現比生成測試好,因為它可以看到你的 implementation code 和 test code,推斷你可能漏了什麼。


不同測試類型的 AI 適用程度

測試類型AI 生成品質人類審查量建議
純函式 Unit Test大量使用 AI
API Endpoint Test中高AI 起草,人類補業務邏輯
Integration Test人類主寫,AI 輔助結構
E2E TestAI 只適合寫 boilerplate
Snapshot TestAI 很適合
效能測試人類主導
安全測試AI 能產 OWASP checklist 測試

未來展望

短期(2026-2027)

  • AI 生成的測試品質會持續提升,特別是有 codebase context 的情況
  • 更好的 mock 策略推斷(基於依賴注入分析)
  • IDE 內即時的測試覆蓋率建議

中期(2027-2028)

  • AI 作為 test reviewer 成為標準流程
  • 基於 production error log 自動產生回歸測試
  • AI 分析 test suite 品質(不只是 coverage 數字)

長期

  • AI 理解業務邏輯後,可能產生有意義的 integration test
  • 但「該測什麼」的決策權,短期內不會離開人類

常見問題

AI 生成的測試算「有寫測試」嗎?

看品質。如果 AI 生成了 100 個測試但都是測 implementation 的,那 coverage 100% 也沒用。重要的是有沒有真正驗證到業務邏輯。AI 生成 + 人類審查 = 有效的測試。AI 生成 + 直接 commit = 自我欺騙。

要怎麼評估 AI 生成的測試品質?

三個指標:1)Mutation Testing 分數(用 Stryker)——AI 生成的測試能不能抓到刻意植入的 bug;2)刪掉某個測試後 coverage 有沒有掉——如果沒掉,這個測試就是廢的;3)改了 implementation 後測試有沒有壞——如果壞了但功能沒變,代表測的是 implementation。

Claude Code 和 Copilot 哪個生成測試比較好?

取決於 context。Claude Code 可以讀整個 codebase 的 context,生成的測試對跨檔案的依賴處理得比較好。Copilot 在 inline 建議方面更流暢,適合邊寫 code 邊補測試。兩個可以互補。

全部用 AI 寫測試,人力可以省多少?

寫測試的時間大約省 40-60%,但 review 測試的時間會增加。整體來說,資深工程師用 AI 輔助可以提升 30-40% 的測試產出效率。但初級工程師如果不審查就直接用,反而會創造更多技術債。

本系列文章

  1. 測試策略(一):測試金字塔
  2. 測試策略(二):Unit vs Integration
  3. 測試策略(三):E2E + 壓力測試
  4. CD 整合
  5. API 契約測試
  6. 安全測試
  7. Smoke + 回歸測試
  8. 測試資料管理
  9. 視覺回歸測試
  10. AI 輔助測試(本篇)
  11. ISO 29119)
  12. 測試相關憑證與學習路徑