Communitygithub.com

AI回归测试

专为AI辅助开发设计的回归测试策略。无需数据库依赖的沙箱模式API测试、自动化Bug检查工作流,以及用于捕捉同一模型既写代码又做审查时产生的盲点的模式。当为AI辅助代码添加回归测试覆盖,或同一模型既编写又审查了代码变更时使用。

AI回归测试 是什么?

该技能为AI辅助开发中的回归测试提供了专业策略,重点解决AI模型在自写自审过程中产生的系统性盲点。它基于一个关键观察:当AI既写代码又审查代码时,会带着相同的假设进入两个环节,导致特定类型的bug(如沙箱/生产路径不一致、SELECT子句遗漏)反复出现。 技能核心包括:沙箱模式API测试框架(基于Vitest和Next.js),无需数据库即可快速验证API响应;按bug发现位置精准编写回归测试的策略(而非追求100%覆盖率);以及集成到`/bug-check`命令中的自动化工作流。 该方案优先支持Claude Code、Cursor、Codex等AI编码工具,通过先运行自动化测试再执行AI审查的流程,将机械性检查与AI分析相结合,有效阻断已知bug的复现,使测试数量随bug修复自然增长。

兼容平台✓Claude Code✓Codex CLI✓Cursor
npx skills add https://github.com/affaan-m/ECC/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",  // ← 发现遗漏后添加
];

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-Check工作流

自定义命令定义

<!-- .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:沙箱/生产路径不匹配

频率:最常见(在3/4的回归案例中观察到)

// 失败: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中项目已消失但DB中仍在
};

// 通过:捕获之前状态并在失败时回滚
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/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

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.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

api-connector-builder

Build a new API connector or provider by matching the target repo

相关技能