AI测试 AI 赋能测试实践 12:从 “写测试” 到 “说测试”——VibeTesting 上篇:体验与落地

EternalRights · 2026年08月04日 · 50 次阅读

前言

        2025 年 2 月,前 Tesla AI 总监 Andrej Karpathy 发了一条后来被刷了 680 万浏览的推文。他说自己发明了一种新的编程方式叫"Vibe Coding"——对着 Cursor 用语音说"把侧栏的 padding 减半",AI 生成的代码一律 Accept All,出错了就把错误信息贴回去让 AI 自己修。他在结尾加了一句:"It's not too bad for throwaway weekend projects."(对抛弃式周末项目来说还不错。)(What is Vibe Coding?)

        十个月后,《柯林斯词典》把"Vibe Coding"选为 2025 年度词汇。✨

        毋庸置疑,现在对于所有的研发而言,代码生成环节的效率几乎得到了史诗级别的提高,如果说原来是小河弯弯,那么现在就是黄河滚滚、激流涌下。🌊

        但是研发效率暴涨的同时,兜底的测试,效率能否收益于 Vibe Coding 呢?答案是很明确的,短期内,所有的测试人员受到了来自 AI 的冲击,受到了来自效率暴涨的测试压力,在 Vibe Coding 上,测试无疑是受益最低的。

        可是,随着测试发展,诞生了 AI 测试。

        AI 测试区别于原有的简单测试开发,融入了 Vibe Coding 的精华,那就是VibeTesting💫

        你拉下 RD 最新的代码,在 Cursor 里打开了这个项目,对着它说:"这个订单接口改过字段,帮我生成接口回归测试,重点覆盖并发下单和优惠券叠加的场景。"AI 自己读代码实现、读 PR 描述、读 PRD、读 git log 里的历史缺陷记录,然后生成了一份 pytest 用例,你瞄一眼逻辑对不对,跑起来,整个过程比德芙🍫还要丝滑。

        但是在这个过程中,你只描述了意图,AI 完成了执行。你仅仅只是"确认了 AI 写的测试有没有表达你的意图"。 这跟 Vibe Coding 的核心体验简直是一模一样——在 Vibe Coding 里,开发者"完全沉浸在编程氛围中,甚至忘记了代码的存在";在 VibeTesting 里,测试者也能够"完全沉浸在测试意图中,甚至忘记测试脚本的存在"。

一、VibeTesting 到底在测什么?

        笔者先理清一个很多人没想明白的问题:VibeTesting 跟"让 AI 生成测试用例"有什么区别?

        区别在于你给了 AI 什么东西。传统的"AI 生成测试用例"是这样:你给它一个接口文档(Swagger),它根据字段生成了一堆合法 / 非法的参数组合。"amount 是 int,所以生成 amount=0、amount=-1、amount=100000 三条用例。"这叫结构驱动的测试生成——AI 的输入是一个结构定义,输出是对这个结构的穷举。

        VibeTesting 多了一层东西:上下文

        你不仅告诉 AI"这个接口的 amount 是 int",你还告诉它:

  • 这个接口上个月出过一个并发超卖的 Bug(BUG-3066),修了但还没回归覆盖
  • 它依赖一个 Apollo 开关,开关没命中时会走旧逻辑——但是旧逻辑上上上周就被废弃了,你最好去服务端代码里面去认真读一下,理解一下现状
  • 测试环境里支付走的是 mock,不要真扣钱

        这些东西其实就是业务上下文。传统的 AI 驱动的测试生成工具不读这些东西,它们只看 Swagger 文档里的参数表。VibeTesting 的核心就是——让 AI 在"理解了这条接口是怎么活在这个系统里的"之后,再生成测试。

        这就解释了为什么"对着 AI 说意图"跟"让 AI 读 Swagger 生成用例"是两回事。前者的输入是意图 + 上下文,后者的输入只有结构定义。

        所以 VibeTesting 给人的体感其实更加强调人与 AI,而非孤立了人、让 AI 自己乱搞。

二、场景一:Charles 接上 AI,一句"帮我看看接口变了什么"

        先说一个最直观的场景。你每天打开 Charles 抓包,需要翻几百条请求,按烂了 ctrl + f,只为找到异常的返回值变化,这不就是最苦力的环节嘛?

        传统的流程:肉眼对比两次抓包 → 判断哪些变更是有意的 → 手动写回归用例。这样非常累,而且非常容易遗漏。

        但是,把 Charles 接上 MCP 之后,流程变成这样:对着 Claude Code 说一句话,AI 就能够自己读流量、自己对比差异、自己标出"有意的变更"和"可能的回归"。所以我们就把最苦力的环节外包给了 AI,而你的付出只是说句话。

搭建步骤:

        Charles MCP Server 是一个开源项目(GitHub: https://github.com/heizaheiza/Charles-mcp,MIT 协议),它把 Charles 的实时流量暴露成了 AI 能调用的工具。

        在你的 Claude Code 或 Cursor 的 MCP 配置里加几行:

{
  "mcpServers": {
    "charles": {
      "command": "npx",
      "args": ["charles-mcp-server"]
    }
  }
}

        配置好之后,你对着 AI 说:

"用 Charles MCP 读取当前 session,对比这次的 /api/order/create 返回值跟上次 baseline 的差异。这次改动范围是订单服务重构(PR #3421),跟用户信息和支付方式有关的字段变更大概率是有意的。标出不在重构范围内的字段变更——那些可能是回归。"

        AI 听罢, 会立刻调用 harvest_data() 拿到流量,对比两次 response body,区分"有意的变更"和"可能的回归",输出类似这样的东西:

### 有意变更(PR #3421 范围内)
✅ .user_name → .username:用户模块字段统一重命名
✅ .payment.channel 删除:支付模块重构

### ⚠️ 潜在回归(不在 PR 范围内)
⚠️ .order.amount 类型从 string 变成 int——订单金额的序列化变更不在本次 PR 描述中
⚠️ .discount 新增{"type":"coupon"}——优惠券逻辑不属于订单服务重构

        你秒级判断🙇 :amount 类型变更是谁改的?问他。discount 新增字段是哪个 PR 带进来的?查一下。AI 替你做了最枯燥的"翻 Charles 对比返回值"这一步,你把精力放在"判断这个变更该不该发生"上。

        这就是 VibeTesting 在流量分析里的落地形态——你说意图("帮我对比这两个版本的差异,标出可疑变更"),AI 执行操作(读流量、分析字段、区分类型)。

三、场景二:AI IDE 里的 VibeTesting——说意图,AI 直接跑测试

        上面的 Charles 场景解决的是"分析已有流量"的问题。但是如果你的工作流里没有 Charles,或者你想让 AI 直接帮你写并执行测试——把场景搬到你的 AI IDE(Cursor / Trae 里都行,下面以 Cursor 为例)。

        这个场景更接近 Vibe Coding 的原生体验。 你打开一个项目,看到一个接口,想给它加回归测试。以前你的流程是:看 Swagger 文档 → 看 git log 里的历史缺陷 → 手写 pytest 用例 → 跑一遍 → 修失败 → 再跑。

        可在 Cursor 里,这就变成了一个对话:

"这是一个订单创建接口 /api/order/create。我打开了 src/api/order.pytests/test_order.py。帮我做一件事:基于这个接口的代码逻辑和 git log 里的历史缺陷,生成一套接口回归测试。重点关注三个东西——并发下单会不会超卖(历史 BUG-3089)、优惠券和满减叠加时金额算得对不对、还有支付回调超时之后订单状态能不能正确流转。"

        Cursor 自己干了几件事:

  1. 读了 order.py 的代码,理解了接口的入参、出参、异常处理逻辑
  2. 读了 git log --oneline -20,找到了 BUG-3089 的修复记录和关联的 PR
  3. 读了已有的 test_order.py,理解了你的项目用的是 pytest + requests 的组合
  4. 生成了 12 条测试用例——每条都带"我为什么测这个"的业务理由,而非 amount=0 这种模板套话:
  • test_concurrent_order_dedup:模拟两个请求同时下单同一件商品,验证只有一单成功(对应 BUG-3089)
  • test_coupon_and_discount_combined:优惠券和满减叠加时验证最终金额(对应历史叠加错乱 Bug)
  • test_payment_callback_timeout:模拟回调超时后查询订单状态是否为"支付超时已取消"
  • test_order_create_apollo_flag:验证 Apollo 开关未命中时走旧逻辑的降级行为

        关键的体感差别:与"AI 帮你写了一堆 assertTrue(true) 来凑覆盖率"不同的是,它生成的每一条测试后面都有一个"我为什么测这个"的业务理由。那个理由来自你给它的上下文:Git 历史、Bug 记录、业务风险区域。

四、VibeTesting 跟"AI 写测试"的本质差别:意图才是第一步

        如果说上一节只是让你觉得"哦 AI 能写测试",那你还没有抓到 VibeTesting 的真正价值。

        我们先回到一个根本问题上:你是怎么决定"该测什么"的?

        过去,你拿到一个需求,脑子里跑的是这样一套逻辑:

  1. 这个功能改了哪些接口、字段?(结构)
  2. 这个模块以前出过什么问题?(历史)
  3. 改了之后会影响哪些下游?(依赖)
  4. 什么样的场景最容易出问题?(风险判断)❓

        前三个问题,传统工具能帮你答。第一个看 Swagger,第二个翻 JIRA,第三个看架构文档。

        但第四个问题——"什么样的场景最容易出问题"——是我们测试工程师的核心能力。 它靠的是你对这个系统的理解和你踩过的坑。

        VibeTesting 要解决的问题其实就是第四个。它把前三步自动化了(AI 读 Swagger、读 git log、读代码依赖关系),然后把第四步的判断交还给你——你只需要告诉 AI"哪些地方容易翻车",它就能据此生成有针对性的测试。

        2026 年的顶级学术会议 ICSE 和 FSE 上,有两个研究把这个思路做到了方法论层面。

        Testora(ICSE 2026,Michael Pradel 团队)做了一件事:它测了"PR 造成的行为变化跟开发者的意图是否一致"。给定一个 PR,它先让 LLM 生成覆盖修改代码的测试,然后比较改之前和改之后的行为差异,再用 PR 的标题、描述、commit message 里的自然语言信息把行为差异分成"有意的"和"无意的"。在 scipy、pandas 等复杂项目上跑了 1274 个 PR,发现了 19 个真实回归 Bug。单次 PR 的成本:12.3 分钟,\$0.003 的 LLM 费用。(Testora arXiv)

        IntentTester(FSE 2026,浙江大学)从另一个角度走——如果你有一组在 Java 项目里跑得好好的测试,现在要迁移到 Python 项目,怎么办?传统做法是一个一个手写适配。IntentTester 不翻译代码,而是抽象测试意图——把测试的逻辑("验证空 JSON 对象解析为 None")提取出来,在目标语言里重新生成。跨语言迁移准确率 85%。(IntentTester)

        这两个研究的共同点:测试的对象是意图。 跟 Vibe Coding 的哲学完全一致——Vibe Coding 里,你描述的是"我想要什么功能",而非"你怎么实现这个功能"。VibeTesting 里,你描述的是"我要验证什么行为",而非"你怎么写断言验证这个行为"。

五、这玩意儿能进 CI 吗?

        当然能。而且比你想象的还要简单。几乎所有的 AI Agent 最佳实践都是进 CI 干活。

        上面的两个场景(Charles 抓包分析 + Cursor 生成用例)都是"你坐在电脑前手动触发"。但实际上它们都可以自动化。

        Charles MCP 在 CI 里是这样跑的:

# CI 触发后,先录制新版本流量
mitmproxy --mode upstream:staging-api.example.com --save-stream-file new_traffic.flow &
# 跑完回归
kill %1
# AI 对比新旧流量差异
claude --print "对比 baseline.flow 和 new_traffic.flow 的差异,只列出新增 4xx/5xx 和字段变更" > diff_report.md

        Cursor 生成的用例可以封装成一个自动化测试用例生成的 Skill,然后 CI 每次触发时按项目上下文自动生成最新的回归用例并执行。

        这两个场景拼在一起,就是一条完整的 VibeTesting 链路:

代码提交 → 
  ① 部署到测试环境 → 
  ② 启动流量录制(Charles MCP/mitmproxy) → 
  ③ AI 生成/更新回归用例(Skill) →
  ④ 执行测试 → 
  ⑤ AI 对比流量差异 → 
  ⑥ 标记"有意变更"和"潜在回归" → 
  ⑦ 结果推送飞书

        每一步都是 AI 替你做的。你做的事情是:描述意图、审核结果、对异常做出判断。

        这就是 VibeTesting 在工作流里的样子——AI 把测试里的重复劳动拿走了,留下需要你判断的部分。

后记

        本篇作为上篇,讲了 VibeTesting 该有的体验:你说意图,AI 执行。两个场景(Charles 抓包分析 + AI IDE 意图驱动生成)是你直接就可以快速入手的——装个 MCP Server,打开 Cursor / Claude Code / Codex,对着它描述你要测什么就行。

        所以可以这么说,对于已有工作经验的测试工程师而言,VibeTesting 就是加速器,如果换做是毫无工作经验的那就是 AI 幻觉的放大器。

        尽管如此,这里却有一个你绕不开的问题:上面说的所有东西,AI 读代码、AI 生成测试、AI 分析流量——都基于一个前提:你设的指标和约束是对的。

        如果你告诉 AI"覆盖率要到 80% 否则别停",它会不会为了达标,而直接改代码?会不会生成一堆 assertTrue(true) 来凑数?会不会偷偷的把覆盖率门槛从 80% 改成自己能到的数字?(尤其是对于 GPT 系列的模型,这种投机取巧,为了达成目的不择手段,在一些情况下会更明显。笔者之前迭代一个 agent 项目的时候,用 pytest 写测试集,AI 在迭代后回归测试的过程中,发现一个 case 没有通过,他竟然不认为是代码的问题,而是测试 case 的问题,他直接把 case 给改了,然后心安理得的通过了,告诉我迭代完了回归成功。我后续审阅了代码 diff 才发现这家伙自己偷偷的改了 case,简直是太鸡贼了!🐍

        答案是会的!而且已经被验证过不止一次。

        所以下篇专门讲这个——我让 AI 写了 275 个测试,全部通过,一个 Bug 都没抓住。 然后讲怎么避免,来一波细致入微的庖丁解牛。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册