Vibe Coding一人即团队系列50: 基于 Claude Code 的多项目测试计划生成与自动化测试实战

纲要

本文围绕 Claude Code 驱动的测试闭环展开,核心内容如下:

  • Claude Code 测试流程
    • 测试计划生成
    • 测试工程结构初始化
    • 测试执行与 HTML 报告输出
  • 关键概念
    • AI 编程时代测试的价值
    • 高风险功能识别
    • 真实断言与无效测试
  • 项目范围
    • 003-fullstack/frontend
    • 003-fullstack/backend
    • uni-app
  • 补充代码示例
    • Node.js 内置 node:test
    • JUnit 5
    • Vitest
    • Playwright
    • 静态 HTML 测试报告
  • 适用版本
    • Node.js 18+
    • JUnit 5.10+
    • Vitest 2.x
    • Playwright 1.4x
    • Spring Boot 3.3.x

背景:为什么 AI 编程时代更需要测试

AI 编程工具能够在极短时间内生成可运行代码,但这并不意味着可以跳过测试。Claude Code 等工具在生成业务代码时,可能无法完全理解边界条件、异常操作、数据一致性以及多模块交互。测试的本质不是单纯寻找 bug,而是保障功能稳定、用户体验正常、数据安全可靠,并最终使项目具备上线条件。

成熟开发流程应遵循"需求 → 开发 → 测试 → 修复 → 上线 → 持续优化"的闭环。在这个闭环中,测试不是上线前的简单页面点击,而是一套完整体系,覆盖功能测试、接口测试、压力测试、安全测试、兼容性测试、自动化测试、用户体验测试和业务逻辑验证。
#mermaid-svg-8mtORVii0V40stYu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8mtORVii0V40stYu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8mtORVii0V40stYu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8mtORVii0V40stYu .error-icon{fill:#552222;}#mermaid-svg-8mtORVii0V40stYu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8mtORVii0V40stYu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8mtORVii0V40stYu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8mtORVii0V40stYu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8mtORVii0V40stYu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8mtORVii0V40stYu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8mtORVii0V40stYu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8mtORVii0V40stYu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8mtORVii0V40stYu .marker.cross{stroke:#333333;}#mermaid-svg-8mtORVii0V40stYu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8mtORVii0V40stYu p{margin:0;}#mermaid-svg-8mtORVii0V40stYu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8mtORVii0V40stYu .cluster-label text{fill:#333;}#mermaid-svg-8mtORVii0V40stYu .cluster-label span{color:#333;}#mermaid-svg-8mtORVii0V40stYu .cluster-label span p{background-color:transparent;}#mermaid-svg-8mtORVii0V40stYu .label text,#mermaid-svg-8mtORVii0V40stYu span{fill:#333;color:#333;}#mermaid-svg-8mtORVii0V40stYu .node rect,#mermaid-svg-8mtORVii0V40stYu .node circle,#mermaid-svg-8mtORVii0V40stYu .node ellipse,#mermaid-svg-8mtORVii0V40stYu .node polygon,#mermaid-svg-8mtORVii0V40stYu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8mtORVii0V40stYu .rough-node .label text,#mermaid-svg-8mtORVii0V40stYu .node .label text,#mermaid-svg-8mtORVii0V40stYu .image-shape .label,#mermaid-svg-8mtORVii0V40stYu .icon-shape .label{text-anchor:middle;}#mermaid-svg-8mtORVii0V40stYu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8mtORVii0V40stYu .rough-node .label,#mermaid-svg-8mtORVii0V40stYu .node .label,#mermaid-svg-8mtORVii0V40stYu .image-shape .label,#mermaid-svg-8mtORVii0V40stYu .icon-shape .label{text-align:center;}#mermaid-svg-8mtORVii0V40stYu .node.clickable{cursor:pointer;}#mermaid-svg-8mtORVii0V40stYu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8mtORVii0V40stYu .arrowheadPath{fill:#333333;}#mermaid-svg-8mtORVii0V40stYu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8mtORVii0V40stYu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8mtORVii0V40stYu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8mtORVii0V40stYu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8mtORVii0V40stYu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8mtORVii0V40stYu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8mtORVii0V40stYu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8mtORVii0V40stYu .cluster text{fill:#333;}#mermaid-svg-8mtORVii0V40stYu .cluster span{color:#333;}#mermaid-svg-8mtORVii0V40stYu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8mtORVii0V40stYu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8mtORVii0V40stYu rect.text{fill:none;stroke-width:0;}#mermaid-svg-8mtORVii0V40stYu .icon-shape,#mermaid-svg-8mtORVii0V40stYu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8mtORVii0V40stYu .icon-shape p,#mermaid-svg-8mtORVii0V40stYu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8mtORVii0V40stYu .icon-shape .label rect,#mermaid-svg-8mtORVii0V40stYu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8mtORVii0V40stYu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8mtORVii0V40stYu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8mtORVii0V40stYu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

需求
开发
测试
发现问题?
修复
上线
持续优化

测试对象与范围裁剪

本次测试范围包含三个项目:003-fullstack 下的 frontendbackend,以及 uni-app 跨端应用。Java 后端项目与后台管理系统暂不纳入本轮执行范围,但可沿用相同流程扩展。

测试输出统一集中到 008-project-test 目录,其中测试计划放入 test-plans,测试报告放入 test-reports。这样可以将测试产物与业务代码解耦,避免后续在多项目中查找测试文档。

dir 复制代码
workspace/
├── 003-fullstack/
│   ├── frontend/
│   └── backend/
├── 008-project-test/
│   ├── test-plans/
│   └── test-reports/
└── uni-app/

测试计划生成:以自然语言驱动 Claude Code

在正式测试前,应先让 Claude Code 分析项目,生成分层测试计划。测试计划提示词需要明确项目路径、分析维度、输出位置以及分项目输出要求。以下是一个可直接使用的测试计划生成提示词模板:

text 复制代码
进入测试阶段,先完整分析当前项目:
项目路径:
- /workspace/003-fullstack/frontend 
- /workspace/003-fullstack/backend
- /workspace/uni-app
 
要求:
1. 识别每个项目的技术栈、目录结构、启动方式
2. 找出每个项目的核心业务模块
3. 找出高风险功能,特别关注资金相关、安全相关、兼容性相关
4. 设计分层测试方案
5. 不要立即写代码,先输出测试计划到 /workspace/008-project-test/test-plans
6. 按不同项目分别输出测试计划,不要合并到同一文档

该提示词将分析维度拆分为技术栈识别、核心业务模块、高风险功能识别与测试方案设计四部分,并要求按项目拆分输出,避免多个项目的计划混在一个文档中。

从生成结果看,frontend 项目会识别出 Excel 导出、图表绘制、localStorage、页面跳转等高风险或兼容性相关功能;backend 项目会重点识别密码存储、加密、SQL 注入等安全类风险,并输出 API 接口清单与接口测试用例;uni-app 会结合移动端特性,剔除不涉及的 Excel 导出能力,并生成跨端差异相关风险清单。

测试工程结构初始化:隔离测试代码与业务代码

测试代码不应侵入业务代码。初始化测试工程时,需要新增 testtests 目录,并让 Claude Code 自行配置测试框架、测试命令和报告输出目录。

text 复制代码
请基于以上三份测试计划,为项目创建测试工程结构。
要求:
1. 不影响现有业务代码
2. 新增 test 或 tests 目录,集中存放测试相关代码
3. 配置测试框架
4. 配置测试命令
5. 配置测试报告输出目录 
6. 给出每个测试文件的作用说明

执行后,三个项目均会生成独立的 testtests 目录。frontend 项目通常包含单元测试、组件测试、集成测试和端到端测试;backend 项目会覆盖安全测试、性能测试和 API 接口测试;uni-app 项目则包含跨端相关测试目录。

目录结构可简化为:

dir 复制代码
003-fullstack/
├── frontend/
│   ├── src/
│   └── tests/
│       ├── unit/
│       ├── e2e/
│       └── reports/
└── backend/
    ├── src/
    └── tests/
        ├── unit/
        ├── integration/
        ├── security/
        └── performance/
 
uni-app/
├── src/
└── tests/
    ├── unit/
    └── e2e/

初始化完成之后,建议先手动检查业务代码是否被改动。如果发现业务代码发生变化,应重新调整提示词,明确"只新增测试相关内容,不修改原有业务代码"的约束条件。

断言与无效测试:从 expect(true).toBe(true) 到真实断言

断言是测试的核心,它表示对系统行为的预期。例如,设定一个安全等级预期后,只有测试结果达到该预期,断言才算通过;如果结果偏离预期,则测试失败。断言必须描述真实业务行为,而不是"永远为真"的无效校验。

无效测试示例:

js 复制代码
expect(true).toBe(true)

这种测试只是不断验证一个本就为真的条件,无法发现业务缺陷,还会浪费测试资源。真正有效的断言需要绑定具体输入、输出或状态变化。

以下示例基于 Node.js 18+ 内置测试运行器,展示一个真实断言。该代码无需额外依赖,保存后可使用 node --test 直接运行。

js 复制代码
// test/assert-demo.test.js
const assert = require('node:assert/strict');
const { test } = require('node:test');
 
function add(a, b) {
  return a + b;
}
 
test('add returns the sum of two numbers', () => {
  assert.equal(add(2, 3), 5);
  assert.equal(add(-1, 1), 0);
});

运行命令如下:

bash 复制代码
node --test test/assert-demo.test.js

如果后端采用 Spring BootJUnit 5,可参考以下断言示例。该示例仅用于展示断言写法,实际项目中应替换为真实业务对象。

java 复制代码
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
 
class CalculatorTest {
    @Test
    void shouldAddTwoNumbers() {
        assertEquals(5, Calculator.add(2, 3));
    }
 
    static class Calculator {
        static int add(int a, int b) {
            return a + b;
        }
    }
}

测试执行与 HTML 报告生成

测试执行阶段需要将测试计划转化为实际测试行为。提示词应强调"优先测试最核心业务流程""严格按计划执行""真实断言""失败可追溯"以及"使用 HTML 报告"。

text 复制代码
请优先为项目的最核心业务流程进行测试。
要求:
1. 严格按照测试计划执行
2. 覆盖所有功能点,如登录、注册、增删改查
3. 每个步骤都要有真实断言
4. 测试失败时自动截图;无法截图时整理完整测试步骤
5. 测试完成后生成 HTML 测试报告
6. 不要使用类似 expect(true).toBe(true) 的无效测试

执行完成后,backend 项目生成 HTML 报告,显示 21 个测试全部通过;frontend 项目总计 76 个测试全部通过;uni-app 项目同样为 100% 通过率。如果测试失败,应将失败原因或日志重新提交给 Claude Code 进行修复,然后按相同流程重新生成报告。

HTML 报告比 Markdown 更适合分发给非技术人员,例如团队负责人或项目相关方。报告中应包含测试项目、通过率、用例总数和失败项列表。

API 速览

本节梳理测试过程中可能使用的核心 API 和命令。

库或工具 适用版本 核心 API / 命令 说明
Node.js 内置测试运行器 18+ test(name, fn) 注册一个测试用例
Node.js 内置断言 18+ assert.equal(actual, expected) 验证实际值与期望值严格相等
JUnit 5 5.10+ @Test 标记一个测试方法
JUnit 5 5.10+ assertEquals(expected, actual) 验证期望值与实际值相等
Vitest 2.x describe / it / expect 前端单元测试与组件测试
Playwright 1.4x page.goto / page.click / expect(page).toHaveURL 端到端测试与截图

如果你使用 Vitest 对前端函数进行断言,可以这样组织测试:

js 复制代码
// test/unit/example.test.js
import { describe, it, expect } from 'vitest';
 
function formatDate(date) {
  return date.toISOString().slice(0, 10);
}
 
describe('formatDate', () => {
  it('returns YYYY-MM-DD format', () => {
    expect(formatDate(new Date('2026-09-03T00:00:00Z'))).toBe('2026-09-03');
  });
});

如果使用 Playwright 做端到端测试,失败时自动截图的关键逻辑如下:

js 复制代码
import { test, expect } from '@playwright/test';
 
test('login page works', async ({ page }) => {
  await page.goto('http://localhost:5173/login');
  await expect(page).toHaveTitle(/登录/);
});

Demo 示例

下面提供一个可直接运行的 HTML 测试报告模板,用于展示后端核心业务测试结果。它不依赖任何外部服务,直接在浏览器中打开即可查看。

html 复制代码
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>backend 核心业务测试报告</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      margin: 40px;
      background: #f8fafc;
      color: #0f172a;
    }
    h1 {
      font-size: 24px;
      margin-bottom: 8px;
    }
    .summary {
      display: flex;
      gap: 24px;
      margin: 24px 0;
    }
    .card {
      background: #ffffff;
      border: 1px solid #e2e8f0;
      border-radius: 12px;
      padding: 16px 24px;
      min-width: 140px;
    }
    .card .label {
      font-size: 12px;
      color: #64748b;
    }
    .card .value {
      font-size: 28px;
      font-weight: 700;
      margin-top: 4px;
    }
    .passed {
      color: #16a34a;
    }
    table {
      width: 100%;
      border-collapse: collapse;
      background: #ffffff;
      border: 1px solid #e2e8f0;
      border-radius: 12px;
      overflow: hidden;
    }
    th, td {
      padding: 12px 16px;
      border-bottom: 1px solid #e2e8f0;
      text-align: left;
    }
    th {
      background: #f1f5f9;
      font-weight: 600;
    }
    tr:last-child td {
      border-bottom: none;
    }
  </style>
</head>
<body>
  <h1>backend 核心业务测试报告</h1>
  <p>测试执行时间:2026-09-03 16:02:17</p>
  <div class="summary">
    <div class="card">
      <div class="label">通过率</div>
      <div class="value passed">100%</div>
    </div>
    <div class="card">
      <div class="label">测试用例总数</div>
      <div class="value">21</div>
    </div>
    <div class="card">
      <div class="label">通过用例</div>
      <div class="value passed">21</div>
    </div>
    <div class="card">
      <div class="label">失败用例</div>
      <div class="value">0</div>
    </div>
  </div>
  <table>
    <thead>
      <tr>
        <th>测试模块</th>
        <th>测试用例</th>
        <th>结果</th>
      </tr>
    </thead>
    <tbody>
      <tr><td>认证接口</td><td>登录成功返回 token</td><td>通过</td></tr>
      <tr><td>用户接口</td><td>注册后数据库存在用户</td><td>通过</td></tr>
      <tr><td>核心业务</td><td>创建、查询、更新、删除数据</td><td>通过</td></tr>
      <tr><td>安全测试</td><td>SQL 注入参数返回参数校验错误</td><td>通过</td></tr>
      <tr><td>安全测试</td><td>密码存储使用 BCrypt 加密</td><td>通过</td></tr>
    </tbody>
  </table>
</body>
</html>

运行说明

将上述内容保存为 test-report.html,使用浏览器直接打开即可查看报告。若需要动态生成报告,可以在 Claude Code 执行测试后,将 JSON 格式的测试结果渲染到该页面中。

代码说明

该 HTML 文件通过 CSS 卡片和表格展示测试汇总信息,适合替代 Markdown 报告,便于分发给非技术人员。页面中的测试数据为静态示例,实际项目中可以将其替换为测试框架输出的真实结果。

技术点总结

该 Demo 演示了以下技术点:使用 HTML 静态页面作为轻量级测试报告载体;使用卡片式布局展示通过率、用例总数和失败数;使用表格展示模块级测试结果;通过浏览器直接打开实现零依赖查看。

参考文档

官方文档

参考链接

总结

本文完整梳理了基于 Claude Code 的多人项目测试闭环:先生成分层测试计划,再初始化隔离于业务代码的测试工程结构,然后通过真实断言执行核心业务流程测试,最后输出 HTML 测试报告。涉及的技术栈包括 Claude CodeNode.js 内置测试运行器、JUnit 5VitestPlaywrightSpring Bootuni-app。高风险功能识别重点关注资金安全、密码存储、SQL 注入、兼容性差异等问题。测试流程强调真实断言,避免 expect(true).toBe(true) 一类无效校验。

相关推荐
小柯南敲键盘34 分钟前
跨马翻译批量图片视频字幕翻译,跨境电商AI智能抠图一站式工具
人工智能·python·音视频·xcode
DevOps老兵36 分钟前
AI Infra实战05:用Helm在K8s中部署vLLM,从安装到压测全流程
人工智能·kubernetes·helm·vllm·大模型推理·ai infra
张--小涛涛43 分钟前
0004 - 机器学习-K近邻算法
人工智能·机器学习·近邻算法
ellenwan202644 分钟前
量化实现的难点,常在规则和流程
人工智能·python
Lethehong1 小时前
ToDesk远程终端怎么用:手机免进桌面排查 Windows,主机名/账号/ipconfig/进程一篇讲透
人工智能
天辛大师1 小时前
天心大师谈重新学会传统文化,AI时代的心经奥义
大数据·人工智能·随机森林·重构·启发式算法
新知图书1 小时前
第 12 章 案例实战:多模态客服智能体
人工智能·语音识别
吴佳浩1 小时前
企业如何把通用大模型训练成行业模型:Continued Pre-Training实战指南
人工智能·神经网络·llm
luckystar513~1 小时前
Hermes 实战 :多渠道接入——日报推送到飞书/Telegram
人工智能·agent·智能体开发·hermes实战·智能体网关