当前位置: 首页
AI教程
AI时代智能体比人类更需要测试驱动开发

AI时代智能体比人类更需要测试驱动开发

热心网友 时间:2026-06-24
转载

TDD 在 AI 时代:为什么 Agent 比人类更需要"先写测试"

上一篇我们探讨了 Subagent-Driven Development 的执行与审核机制。但归根结底,审核只能发现问题,却无法从根源预防问题。Superpowers 的做法是从源头就扼住问题的咽喉——强制 Agent 必须先编写测试,再着手实现功能。

TDD 在 AI 时代:为什么 Agent 比人类更需要

别误会,这并非什么新鲜概念——测试驱动开发(TDD)已经存在 20 多年了。但 Superpowers 对 TDD 的理解与处理方式,与传统认知截然不同:它不是在强调"TDD 是一种优秀的开发实践",而是在宣称"对于 AI Agent 而言,TDD 是唯一能证明代码正确的途径"。这个出发点,让一切都有了不同的意义。

为什么 AI Agent 比人类更需要测试驱动开发

人类开发者不做 TDD,至少还有几层兜底机制:可以手动测试、可以用 IDE 调试器、可以运行程序查看输出、可以凭经验判断边界条件。但 AI Agent 不具备这些——它无法"运行程序看看对不对"(除非配置了自动化执行环境),它的"验证"手段只有两个:

  1. 自我推理代码逻辑是否正确——但这一点极其不可靠,因为模型对自己编写的代码存在盲点。
  2. 执行自动化测试。

如果没有测试,Agent 唯一的验证方式就是自我推理。而模型最擅长的事情之一,恰恰是"合理化解释自己的错误"——你让它审查自己写的代码,它大概率会说"没问题,一切正常"。

TDD 正是打破这个循环的关键:先写测试,测试失败,再写代码让它通过。这个过程引入了客观、可验证的中间步骤,完全不依赖 Agent 的自我判断。

铁律:没有失败的测试就不能写代码

NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST

这是 TDD skill 中的铁律——全大写、无条件、没有例外。违反会怎样?答案非常直接:

Write code before the test? Delete it. Start over.No exceptions:- Don't keep it as "reference"- Don't "adapt" it while writing tests- Don't look at it- Delete means deleteImplement fresh from tests. Period.

注意,这里说的不是"测试没写好需要修改"——而是如果你先写了生产代码再补测试,代码直接删除,没有商量余地。为什么如此极端?

因为一旦代码已经存在,你写的测试会无意识地去"验证现有行为",而不是"定义期望行为"。你会看着代码写断言,测试变成了对实现的确认,而不是对需求的规约。这个心理陷阱,人类会犯,AI Agent 更会犯。

Red-Green-Refactor 循环

TDD 的核心循环包含三步,每一步都带有强制验证点:

RED → Verify RED → GREEN → Verify GREEN → REFACTOR → (stay green) → next RED

RED:编写一个失败的测试

编写一个最小化的测试,描述你期望的行为:

test('retries failed operations 3 times', async () => {let attempts = 0;const operation = () => {attempts++;if (attempts < 3) throw new Error('fail');return 'success';};const result = await retryOperation(operation);expect(result).toBe('success');expect(attempts).toBe(3);});

一个测试只测一个行为。测试的名称要能让人一眼看出"在什么场景下预期什么结果"。

对比一下反面教材:

test('retry works', async () => {const mock = jest.fn().mockRejectedValueOnce(new Error()).mockRejectedValueOnce(new Error()).mockResolvedValueOnce('success');await retryOperation(mock);expect(mock).toHa veBeenCalledTimes(3);});

问题很明显:名称模糊——"retry works"说了等于没说;而且测试的是 mock 的调用次数,而非真实行为。

Verify RED:确认测试确实失败了

MANDATORY. Never skip.

运行测试,确认它:

  • 是失败(fail)而不是报错(error)——两者有本质区别
  • 失败原因是"功能不存在",而不是"拼写错误"
  • 失败信息符合预期

如果测试直接通过了怎么办?说明你在测试已有行为——要么功能已经存在,要么测试写错了。修改测试,而不是跳过验证。

这一步的意义在于:证明测试确实能检测到"功能缺失"。如果你跳过这一步直接写实现,你永远不知道这个测试到底有没有在检测什么东西。

GREEN:最小化实现

写刚好能让测试通过的代码,不多不少:

async function retryOperation(fn: () => Promise): Promise {for (let i = 0; i < 3; i++) {try {return await fn();} catch (e) {if (i === 2) throw e;}}throw new Error('unreachable');}

对比一下过度实现的样子:

async function retryOperation(fn: () => Promise,options?: {maxRetries?: number;backoff?: 'linear' | 'exponential';onRetry?: (attempt: number) => void;}): Promise {// YAGNI - 测试没要求这些功能}

关键原则:不要添加测试没要求的功能,不要重构其他代码,不要做任何"超越测试"的优化。

Verify GREEN:确认测试通过

运行测试,确认:

  • 新测试通过
  • 其他所有测试仍然通过
  • 没有 warning 或 error

Test fails? Fix code, not test.Other tests fail? Fix now.

REFACTOR:清理代码

只有在 GREEN 之后才能进行重构:

  • 消除重复
  • 改善命名
  • 提取辅助函数

约束很明确:重构不能改变行为——测试必须始终保持绿色。

然后:下一个 RED

回到起点,写下一条测试。整个循环是增量式的——每次只前进一小步,每一步都有据可查。

为什么顺序是铁律

Superpowers 用了很大篇幅来解释"为什么不能先写代码后补测试"。这些不是教条式的论证,而是针对模型最容易犯的错误而设计的。

"先写代码再补测试,效果一样"

Tests written after code pass immediately. Passing immediately proves nothing:- Might test wrong thing- Might test implementation, not beha vior- Might miss edge cases you forgot- You never saw it catch the bugTest-first forces you to see the test fail, proving it actually tests something.

这一点对 AI Agent 尤其致命——Agent 补的测试几乎一定是基于它已经写好的实现。它不会故意写出不通过的测试,这就完全失去了 TDD 的意义。

"我已经手动验证了所有边界情况"

Manual testing is ad-hoc. You think you tested everything but:- No record of what you tested- Can't re-run when code changes- Easy to forget cases under pressure- "It worked when I tried it" ≠ comprehensive

"删掉已经写好的代码太浪费了"

Sunk cost fallacy. The time is already gone. Your choice now:- Delete and rewrite with TDD (X more hours, high confidence)- Keep it and add tests after (30 min, low confidence, likely bugs)The "waste" is keeping code you can't trust.

"TDD 是教条主义,务实才是正道"

TDD IS pragmatic:- Finds bugs before commit (faster than debugging after)- Prevents regressions (tests catch breaks immediately)- Documents beha vior (tests show how to use code)- Enables refactoring (change freely, tests catch breaks)"Pragmatic" shortcuts = debugging in production = slower.

常见借口对照表

这是 Superpowers 的 Rationalization Prevention 机制在 TDD 领域的具体应用——提前把所有可能的借口摆到桌面上,逐一击破:

借口现实
"Too simple to test"Simple code breaks. Test takes 30 seconds.
"I'll test after"Tests passing immediately prove nothing.
"Tests after achieve same goals"Tests-after = "what does this do?" Tests-first = "what should this do?"
"Already manually tested"Ad-hoc ≠ systematic. No record, can't re-run.
"Deleting X hours is wasteful"Sunk cost fallacy. Keeping unverified code is technical debt.
"Keep as reference, write tests first"You'll adapt it. That's testing after. Delete means delete.
"Need to explore first"Fine. Throw away exploration, start with TDD.
"Test hard = design unclear"Listen to test. Hard to test = hard to use.
"TDD will slow me down"TDD faster than debugging. Pragmatic = test-first.
"Manual test faster"Manual doesn't prove edge cases. You'll re-test every change.
"Existing code has no tests"You're improving it. Add tests for existing code.

注意第 7 条"Need to explore first"——Superpowers 允许探索性编码(spike),但要求探索完成后把所有代码删掉,从 TDD 重新开始。探索的目的是理解问题,而不是产出代码。

警告信号:什么时候 TDD 做错了

- Code before test- Test after implementation- Test passes immediately- Can't explain why test failed- Tests added "later"- Rationalizing "just this once"- "I already manually tested it"- "Tests after achieve the same purpose"- "It's about spirit not ritual"- "Keep as reference" or "adapt existing code"- "Already spent X hours, deleting is wasteful"- "TDD is dogmatic, I'm being pragmatic"- "This is different because..."All of these mean: Delete code. Start over with TDD.

最后一条 "This is different because..." 是最隐蔽的——模型总能找到"这次情况特殊"的理由。Superpowers 的回答很简单:没有"特殊情况"。

优质测试的标准

维度好的测试坏的测试
Minimal只测一件事。名字里有"and"?拆开。test('validates email and domain and whitespace')
Clear名字描述行为test('test1')
Shows intent展示期望的 API 用法让人看不出代码应该怎么用
Real code用真实代码(mock 只在不可避免时用)到处 mock

一个关键原则:测试应该展示 API 的理想用法。如果你的测试代码写得很丑陋、很复杂,那说明 API 设计本身有问题。

Test hard = design unclear. Listen to test. Hard to test = hard to use.

Bug 修复的 TDD 流程

Bug 修复特别适合 TDD——先写测试重现 bug,再修复,一劳永逸。

假设有个 bug:空邮箱被接受了。

RED(重现 bug):

test('rejects empty email', async () => {const result = await submitForm({ email: '' });expect(result.error).toBe('Email required');});

Verify RED:

$ npm testFAIL: expected 'Email required', got undefined

测试失败了,证明 bug 确实存在。

GREEN(最小修复):

function submitForm(data: FormData) {if (!data.email?.trim()) {return { error: 'Email required' };}// ...}

Verify GREEN:

$ npm testPASS

REFACTOR:如果有多个字段需要类似验证,提取验证逻辑。

这个流程的好处在于:修完 bug 后,这个测试永远留在测试套件里。如果以后有人改动了相关代码导致 bug 回归,测试会立即捕获。

Bug found? Write failing test reproducing it. Follow TDD cycle. Test proves fix and prevents regression.Never fix bugs without a test.

遇到困难:测试写不出来怎么办

问题解法
不知道怎么测先写理想的 API 调用方式。先写断言。如果还是不行,去问你的 human partner。
测试太复杂说明设计太复杂了。简化接口。
必须 mock 所有东西代码耦合太紧。用依赖注入来解耦。
测试 setup 太大提取 helper。如果仍然复杂,那就说明设计需要简化。

核心理念:测试困难是设计问题的症状,而不是 TDD 方法论的问题。如果测试很难写,不是"TDD 不适合这个场景"——而是"代码设计需要改进"。

验证检查清单

每次任务完成前的自查清单:

Before marking work complete:- [ ] Every new function/method has a test- [ ] Watched each test fail before implementing- [ ] Each test failed for expected reason (feature missing, not typo)- [ ] Wrote minimal code to pass each test- [ ] All tests pass- [ ] Output pristine (no errors, warnings)- [ ] Tests use real code (mocks only if una voidable)- [ ] Edge cases and errors coveredCan't check all boxes? You skipped TDD. Start over.

TDD 和上一篇的 SDD 如何配合

在 Subagent-Driven Development 流程中,TDD 在 Implementer subagent 环节发挥作用:

Coordinator 分派 taskImplementer subagent 开始执行├── RED: 写失败测试├── Verify RED: 运行确认失败├── GREEN: 最小实现├── Verify GREEN: 运行确认通过├── REFACTOR: 清理└── CommitSpec Reviewer: 实现匹配 spec 吗?Code Quality Reviewer: 代码质量如何?

Implementer 内部用 TDD 保证自己写的代码正确。Reviewer 从外部视角验证它是否满足 spec 和质量标准。内部保障(TDD)+ 外部审核(Review)= 双重质量闭环。

对 AI Agent 的特殊意义

TDD 对人类来说是"更好的实践"。但对 AI Agent 而言,TDD 几乎是"唯一可靠的验证手段":

验证方式人类Agent
手动运行程序✅ 随时可做❌ 需要特殊环境配置
IDE 调试器✅ 设断点、看变量❌ 不可用
直觉/经验判断✅ 有一定可靠性❌ 模型会 rationalize
自动化测试✅ 可选✅ 唯一客观手段
自我 review✅ 有一定效果⚠️ 严重偏向自己的代码

这就是为什么 Superpowers 把 TDD 从"推荐实践"升级为"铁律"——不是因为教条,而是因为 Agent 没有其他可靠的质量保障手段。

实践建议

你不需要 Superpowers 也能让 Agent 做 TDD

在你的 CLAUDE.md 或 system prompt 里加上类似的约束:

## TDD 铁律所有新功能和 bug 修复必须遵循 RED-GREEN-REFACTOR:1. 先写一个失败的测试2. 运行测试确认它失败了(不是报错,是失败)3. 写最少的代码让测试通过4. 运行测试确认通过5. 需要的话清理代码违反(先写代码再补测试)→ 删除代码从测试重新开始。

关键是强制"Verify RED"

大多数 Agent 愿意先写测试——但它们经常跳过"运行测试确认失败"这一步。这一步是 TDD 的灵魂:如果你没看到测试失败,你就不知道它到底在检测什么。

If you didn't watch the test fail, you don't know if it tests the right thing.

用借口对照表对抗模型的偷懒

模型会找各种理由跳过 TDD。提前把这些理由列出来并标记为"这不是合理的跳过理由"——这就是 Rationalization Prevention 的力量。

总结

Superpowers 对 TDD 的处理揭示了一个深层洞察:AI Agent 需要 TDD 不是因为"好的开发习惯",而是因为自动化测试是它唯一的客观质量验证手段。

没有 TDD 的 Agent 只能靠自我推理来判断代码对不对——而这恰恰是最不可靠的方式。TDD 提供了客观、可重复、不依赖自我判断的验证路径。

下一篇是本系列的终章:当你想创建自己的 Skill(行为塑造代码)时,怎么用"压力测试"来确保它真的能约束 Agent——Writing Skills 的 TDD。

直接拿走:加到 CLAUDE.md 的 TDD 铁律

不需要 Superpowers。把下面这段加到你的 CLAUDE.md 里:

## TDD 铁律NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST.违反后果:- 测试之前写了代码?删掉,从头来。- 不要保留"参考"、不要"适配"、不要看它。删除就是删除。Red-Green-Refactor 循环:1. RED:写一个最小的失败测试,跑一遍确认它失败2. GREEN:写最少的代码让测试通过,跑一遍确认通过3. REFACTOR:测试通过后清理代码4. 每一步都要实际执行命令看输出——"我觉得会通过"不算。禁止用语:should pass、probably works、seems right、I tested it manually

本文素材来源:obra/superpowers/skills/test-driven-development/SKILL.md

来源:https://juejin.cn/post/7654139492442046527

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
阿里云Qoder CN灵码AI助手免费版及credits计费指南

阿里云Qoder CN灵码AI助手免费版及credits计费指南

阿里云QoderCN(原通义灵码)是一款AI智能编码助手,提供IDE插件、独立IDE等形态,覆盖编码及日常办公场景。产品分个人社区版(免费)、个人专业版、企业标准版和企业VPC版,采用Credits计费模式,支持多种AI模型。

时间:2026-07-06 16:30
基于大模型的城市文旅知识图谱构建与内容分发

基于大模型的城市文旅知识图谱构建与内容分发

大模型构建城市知识图谱时优先采信权威信源。贵港西江传媒联合《度假旅游》杂志,通过本地采编、期刊发布、阿里云多平台分发模式,产出产业文旅等结构化内容,提升AI知识库收录权重,为城市品牌长效传播提供可复制路径。

时间:2026-07-06 16:30
贵州文旅AIGEO内容运营本地媒体落地实践

贵州文旅AIGEO内容运营本地媒体落地实践

针对贵州文旅行业在阿里云平台的内容运营痛点,总结合规发文规则,包括弱化营销、避免引流信息与极限词。以《度假旅游杂志》在贵阳设立本地化运营站点为例,为黔域文旅商家产出合规原创内容,提升AI平台收录权重。同时指出商家常踩的审核红线,强调以干货分享获取自然流量。

时间:2026-07-06 16:29
阿里内部禁用Claude Code OpenCode成替代方案

阿里内部禁用Claude Code OpenCode成替代方案

ClaudeCode对国内用户定向封禁,网传阿里内部已全面禁用。OpenCode作为开源替代,支持接入多种AI模型,通过CCSwitch或手动配置可无缝迁移原有MCP与AgentSkill,规避账号风险。

时间:2026-07-06 16:29
年实测Homebrew安装配置国内源多种安装方式一篇搞定

年实测Homebrew安装配置国内源多种安装方式一篇搞定

Homebrew是macOS上流行的包管理工具,提供pkg安装包、脚本安装和Git克隆等多种安装方式。国内用户推荐使用镜像脚本安装并配置中科大或清华大学镜像源以加速下载。常用命令包括brewinstall安装工具、brewinstall--cask安装图形应用、brewupdate更新及brewdoctor诊断环境。

时间:2026-07-06 16:29
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜