Communitygithub.com

AI回归测试

针对AI辅助开发的回归测试策略。无数据库依赖的沙箱模式API测试、自动化缺陷检查工作流,以及捕获同一模型编写并审查代码时产生的AI盲点的模式。用于为AI辅助代码增加回归覆盖,或当同一模型既编写又审查了代码变更时。

AI回归测试 是什么?

该技能专门解决AI辅助开发中一个特定的问题:当同一个AI模型既编写代码又审查代码时,它会将相同的假设带入两个步骤,从而产生同类型的系统性缺陷。技能文档详细记录了这种模式,并提供了可操作的测试策略,重点是利用项目的沙箱/模拟模式进行快速、无数据库的API测试。它提供了使用Vitest和Next.js App Router设置测试环境的完整代码示例,包括创建测试请求和断言响应结构的辅助函数。技能还定义了一个名为“/bug-check”的自定义工作流,该工作流优先运行自动化测试和类型检查,然后才进行AI代码审查,从而在审查过程早期捕获回归缺陷。文档中记录了四种常见的AI回归模式(沙箱/生产路径不一致、SELECT子句遗漏、错误状态泄漏、缺乏回滚的乐观更新),并提供了每种模式的具体测试和修复策略。该技能适用于Claude Code、Cursor和Codex等AI编码代理,其核心原则是“为发现的bug编写测试,而不是为工作的代码编写测试”,从而让测试集随着缺陷修复而有机增长。

兼容平台✓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或类似的审查命令
  • 存在多个代码路径(沙箱与生产、功能开关等)

核心问题

当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);
      }
    }
  });
});

将测试集成到缺陷检查工作流中

自定义命令定义

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

## 步骤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-check将捕获修复是否被破坏

常见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-check的第一步运行
  • 保持测试快速(沙箱模式下总计< 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.

相关技能