Communitygithub.com

AI 回歸測試策略

針對 AI 輔助開發的回歸測試策略。包括無需資料庫的沙箱模式 API 測試、自動化 Bug 檢查工作流程,以及用於捕捉 AI 盲點(同一個模型既寫程式碼又審查程式碼)的模式。當你想為 AI 輔助編寫的程式碼增加回歸測試覆蓋,或當同一個模型既修改又審查了變更時使用。

AI 回歸測試策略 是什麼?

此技能專門為 AI 輔助開發設計了一套回歸測試策略。其核心是解決一個嚴重的盲點問題:當同一個 AI 模型既編寫程式碼又審查程式碼時,它會帶著同樣的假設進入這兩個步驟,導致系統性的錯誤模式(例如,同一個 Bug 可能被引入四次)。技能提供了具體的實作方案,包括如何使用 Vitest 和 Next.js 在沙箱模式下進行無資料庫的 API 測試、如何撰寫針對已發現 Bug 的回歸測試(而非追求全面覆蓋率),以及一個整合了自動化測試與 AI 程式碼審查的 `/bug-check` 命令工作流程。該技能支援 Claude Code、Cursor 和 Codex 等主流程式碼助手平台,並詳細說明了四種最常見的 AI 回歸模式(沙箱/生產路徑不一致、SELECT 子句遺漏、錯誤狀態洩漏、缺少樂觀更新回滾)以及對應的測試策略。

相容平台✓Claude Code✓Codex CLI✓Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/ai-regression-testing

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

AI 回歸測試

專為 AI 輔助開發設計的測試模式,當同一個模型既編寫程式碼又審查程式碼時,會產生只有自動化測試才能捕捉的系統性盲點。

何時啟用

  • AI 代理(Claude Code、Cursor、Codex)已修改 API 路由或後端邏輯
  • 發現並修復了一個 Bug,需要防止它再次引入
  • 專案擁有沙箱/模擬模式,可用於無資料庫測試
  • 在程式碼變更後執行 /bug-check 或類似的審查命令
  • 存在多個程式碼路徑(沙箱 vs 生產環境、功能開關等)

核心問題

當 AI 編寫程式碼然後審查自己的程式碼時,它會將相同的假設帶入這兩個步驟。這會造成一個可預測的失敗模式:

AI 編寫修復 → AI 審查修復 → AI 說「看起來正確」 → Bug 仍然存在

真實世界範例(在生產環境中觀察到):

修復 1:在 API 回應中加入 notification_settings
  → 忘記將其加入 SELECT 查詢
  → AI 審查時遺漏了(同一個盲點)

修復 2:將其加入 SELECT 查詢
  → TypeScript 建置錯誤(欄位不在生成的型別中)
  → AI 審查了修復 1 但沒發現 SELECT 的問題

修復 3:改成 SELECT *
  → 修復了生產環境路徑,但忘記了沙箱路徑
  → AI 審查時再次遺漏(第 4 次發生)

修復 4:測試在第一次執行時立即捕捉到 PASS:

模式:沙箱/生產環境路徑不一致 是 AI 引入回歸問題的頭號原因。

沙箱模式 API 測試

大多數具有 AI 友善架構的專案都有一個沙箱/模擬模式。這是實現快速、無資料庫 API 測試的關鍵。

設定(Vitest + Next.js App Router)

// vitest.config.ts
import { defineConfig } from "vitest/config";
import path from "path";

export default defineConfig({
  test: {
    environment: "node",
    globals: true,
    include: ["__tests__/**/*.test.ts"],
    setupFiles: ["__tests__/setup.ts"],
  },
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "."),
    },
  },
});
// __tests__/setup.ts
// 強制沙箱模式 — 不需要資料庫
process.env.SANDBOX_MODE = "true";
process.env.NEXT_PUBLIC_SUPABASE_URL = "";
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY = "";

用於 Next.js API 路由的測試輔助函式

// __tests__/helpers.ts
import { NextRequest } from "next/server";

export function createTestRequest(
  url: string,
  options?: {
    method?: string;
    body?: Record<string, unknown>;
    headers?: Record<string, string>;
    sandboxUserId?: string;
  },
): NextRequest {
  const { method = "GET", body, headers = {}, sandboxUserId } = options || {};
  const fullUrl = url.startsWith("http") ? url : `http://localhost:3000${url}`;
  const reqHeaders: Record<string, string> = { ...headers };

  if (sandboxUserId) {
    reqHeaders["x-sandbox-user-id"] = sandboxUserId;
  }

  const init: { method: string; headers: Record<string, string>; body?: string } = {
    method,
    headers: reqHeaders,
  };

  if (body) {
    init.body = JSON.stringify(body);
    reqHeaders["content-type"] = "application/json";
  }

  return new NextRequest(fullUrl, init);
}

export async function parseResponse(response: Response) {
  const json = await response.json();
  return { status: response.status, json };
}

撰寫回歸測試

關鍵原則:針對已發現的 Bug 撰寫測試,而不是針對正常運作的程式碼。

// __tests__/api/user/profile.test.ts
import { describe, it, expect } from "vitest";
import { createTestRequest, parseResponse } from "../../helpers";
import { GET, PATCH } from "@/app/api/user/profile/route";

// 定義合約 — 回應中必須包含哪些欄位
const REQUIRED_FIELDS = [
  "id",
  "email",
  "full_name",
  "phone",
  "role",
  "created_at",
  "avatar_url",
  "notification_settings",  // ← 在發現 Bug 遺漏後加入
];

describe("GET /api/user/profile", () => {
  it("回傳所有必要欄位", async () => {
    const req = createTestRequest("/api/user/profile");
    const res = await GET(req);
    const { status, json } = await parseResponse(res);

    expect(status).toBe(200);
    for (const field of REQUIRED_FIELDS) {
      expect(json.data).toHaveProperty(field);
    }
  });

  // 回歸測試 — 這個確切的 Bug 被 AI 引入了 4 次
  it("notification_settings 不應為 undefined(BUG-R1 回歸)", async () => {
    const req = createTestRequest("/api/user/profile");
    const res = await GET(req);
    const { json } = await parseResponse(res);

    expect("notification_settings" in json.data).toBe(true);
    const ns = json.data.notification_settings;
    expect(ns === null || typeof ns === "object").toBe(true);
  });
});

測試沙箱/生產環境一致性

最常見的 AI 回歸問題:修復了生產環境路徑,但忘記了沙箱路徑(反之亦然)。

// 測試沙箱回應是否符合預期的合約
describe("GET /api/user/messages(對話列表)", () => {
  it("在沙箱模式中包含 partner_name", async () => {
    const req = createTestRequest("/api/user/messages", {
      sandboxUserId: "user-001",
    });
    const res = await GET(req);
    const { json } = await parseResponse(res);

    // 這捕捉到了一個 Bug:partner_name 被加入到了生產環境路徑,但沒有加入到沙箱路徑
    if (json.data.length > 0) {
      for (const conv of json.data) {
        expect("partner_name" in conv).toBe(true);
      }
    }
  });
});

將測試整合到 Bug 檢查工作流程中

自訂命令定義

<!-- .claude/commands/bug-check.md -->
# Bug 檢查

## 步驟 1:自動化測試(強制執行,不可跳過)

在進行任何程式碼審查之前,先執行這些命令:

    npm run test       # Vitest 測試套件
    npm run build      # TypeScript 型別檢查 + 建置

- 如果測試失敗 → 視為最高優先級 Bug 回報
- 如果建置失敗 → 將型別錯誤視為最高優先級回報
- 只有兩者都通過,才能繼續進行步驟 2

## 步驟 2:程式碼審查(AI 審查)

1. 沙箱 / 生產環境路徑一致性
2. API 回應形狀是否符合前端期望
3. SELECT 子句完整性
4. 包含回滾的錯誤處理
5. 樂觀更新的競爭條件

## 步驟 3:針對每個已修復的 Bug,提出一個回歸測試

工作流程

使用者:「バグチェックして」(或 "/bug-check")
  │
  ├─ 步驟 1:npm run test
  │   ├─ 失敗 → 以機械化方式發現 Bug(無需 AI 判斷)
  │   └─ 通過 → 繼續
  │
  ├─ 步驟 2:npm run build
  │   ├─ 失敗 → 以機械化方式發現型別錯誤
  │   └─ 通過 → 繼續
  │
  ├─ 步驟 3:AI 程式碼審查(記住已知的盲點)
  │   └─ 報告發現
  │
  └─ 步驟 4:為每個修復編寫一個回歸測試
      └─ 下次 Bug 檢查會捕捉到修復是否被破壞

常見的 AI 回歸模式

模式 1:沙箱/生產環境路徑不匹配

頻率:最常見(在 4 個回歸問題中觀察到 3 次)

// 失敗:AI 僅將欄位加入生產環境路徑
if (isSandboxMode()) {
  return { data: { id, email, name } };  // 缺少新欄位
}
// 生產環境路徑
return { data: { id, email, name, notification_settings } };

// 通過:兩個路徑必須回傳相同的形狀
if (isSandboxMode()) {
  return { data: { id, email, name, notification_settings: null } };
}
return { data: { id, email, name, notification_settings } };

用來捕捉的測試:

it("沙箱和生產環境回傳相同的欄位", async () => {
  // 在測試環境中,沙箱模式被強制開啟
  const res = await GET(createTestRequest("/api/user/profile"));
  const { json } = await parseResponse(res);

  for (const field of REQUIRED_FIELDS) {
    expect(json.data).toHaveProperty(field);
  }
});

模式 2:SELECT 子句遺漏

頻率:使用 Supabase/Prisma 時常見,尤其是在加入新欄位時

// 失敗:新欄位加入到了回應,但沒有加入到 SELECT
const { data } = await supabase
  .from("users")
  .select("id, email, name")  // 這裡沒有 notification_settings
  .single();

return { data: { ...data, notification_settings: data.notification_settings } };
// → notification_settings 總是 undefined

// 通過:使用 SELECT * 或明確包含新欄位
const { data } = await supabase
  .from("users")
  .select("*")
  .single();

模式 3:錯誤狀態洩漏

頻率:中等 — 在為現有元件加入錯誤處理時

// 失敗:設定了錯誤狀態,但舊資料沒有清除
catch (err) {
  setError("載入失敗");
  // reservations 仍然顯示來自上一個標籤頁的資料!
}

// 通過:在錯誤時清除相關狀態
catch (err) {
  setReservations([]);  // 清除過時資料
  setError("載入失敗");
}

模式 4:缺少適當回滾的樂觀更新

// 失敗:失敗時沒有回滾
const handleRemove = async (id: string) => {
  setItems(prev => prev.filter(i => i.id !== id));
  await fetch(`/api/items/${id}`, { method: "DELETE" });
  // 如果 API 失敗,項目從 UI 中消失,但仍然存在於資料庫中
};

// 通過:捕獲先前的狀態並在失敗時回滾
const handleRemove = async (id: string) => {
  const prevItems = [...items];
  setItems(prev => prev.filter(i => i.id !== id));
  try {
    const res = await fetch(`/api/items/${id}`, { method: "DELETE" });
    if (!res.ok) throw new Error("API 錯誤");
  } catch {
    setItems(prevItems);  // 回滾
    alert("削除に失敗しました");
  }
};

策略:在發現 Bug 的地方進行測試

不要追求 100% 的覆蓋率。相反地:

在 /api/user/profile 發現 Bug → 為 profile API 撰寫測試
在 /api/user/messages 發現 Bug → 為 messages API 撰寫測試
在 /api/user/favorites 發現 Bug → 為 favorites API 撰寫測試
在 /api/user/notifications 沒有 Bug → 暫時不要寫測試

為什麼這在 AI 開發中有效:

  1. AI 傾向於反覆犯下同一類型的錯誤
  2. Bug 集中在複雜的區域(認證、多路徑邏輯、狀態管理)
  3. 一旦經過測試,那個確切的回歸問題不可能再次發生
  4. 測試數量隨著 Bug 修復而自然增長 — 不會浪費精力

快速參考

AI 回歸模式測試策略優先級
沙箱/生產環境不匹配在沙箱模式下斷言相同的回應形狀高
SELECT 子句遺漏斷言回應中的所有必要欄位高
錯誤狀態洩漏斷言錯誤時的狀態清理中
缺少回滾斷言 API 失敗時狀態被恢復中
型別轉換掩蓋 null斷言欄位不是 undefined中

該做 / 不該做

該做:

  • 發現 Bug 後立即撰寫測試(如果可能,在修復之前)
  • 測試 API 回應的形狀,而不是實作細節
  • 將測試作為每次 Bug 檢查的第一步
  • 保持測試快速(使用沙箱模式總時間 < 1 秒)
  • 以它們要預防的 Bug 命名測試(例如「BUG-R1 回歸」)

不該做:

  • 為從未有過 Bug 的程式碼撰寫測試
  • 相信 AI 的自我審查可以替代自動化測試
  • 因為「只是模擬資料」而跳過沙箱路徑測試
  • 在單元測試就足夠時撰寫整合測試
  • 追求覆蓋率百分比 — 目標應是防止回歸

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

相關技能