用 AI 写代码最怕什么?不是写不出来,是写乱了------改了 A 功能碰坏 B 功能,越到后面越不敢动。我这个小程序 6 天写了 9000 行、44 个云函数,到第 6 天还敢大改首页,靠的就是一套流程和 84 个测试。这篇拆开讲。

一、核心流程:spec → plan → TDD
我没有让 AI「想到哪写到哪」,而是走了一条接近真实团队协作的流程:
需求 → spec(设计文档)→ plan(实施计划)→ TDD(先写测试)→ 实现 → 验证
- spec:这个模块解决什么问题、数据怎么存、边界情况有哪些。AI 出方案,我拍板。
- plan:把 spec 拆成可执行的小步骤,定好顺序和验收标准。
- TDD :先写测试,再写实现。测试定义了「做对是什么样」,实现的目标是让它变绿。
- 验证:每个里程碑结束,跑全套测试,全绿才算完。
我的角色是「产品 + 架构 + 验收」,AI 是「全栈开发」。我不用懂每行代码怎么写,但必须懂「做对没有」。
二、为什么必须先写测试
AI 写代码最大的风险是「看起来对」。它会给你一个语法正确、逻辑貌似合理、但有隐藏 bug 的实现,而且写得又快又自信。
测试的价值就是把「对不对」从「看起来」变成「跑得过」:
- 测试先行,等于在写实现之前,先把「什么叫对」钉死。AI 不能糊弄,因为有客观的判定标准。
- 每次改动后全量跑一遍,旧功能有没有被碰坏,立刻知道。这就是敢快速迭代的底气。
没有这个,AI 帮你写得越快,给你埋的雷就越多。

三、测试数是「攒」出来的,不是一次写完
这套流程最直观的证据,是测试数随里程碑一路涨:
| 里程碑 | 交付 | 测试累计 |
|---|---|---|
| M2 | 日历 + 疫苗计划 | 31 |
| M3 | 生长 + 影像档案 | 42 |
| M4 | 我的页 + 证件夹 | 57 |
| M5 | 喂养分布图 + 流水账 | 62 |
| M6 | 首页 Hub + 社交圈子 | 84 |

注意这个节奏:每加一个功能模块,先把它的测试补齐,再往下走。测试像滚雪球一样跟着功能长。到 M6 时,前面所有模块都还在测试的保护网下,所以我敢在最后一天重构首页------反正改坏了,84 个测试会立刻喊出来。
四、一个具体的测试长什么样
拿「记录汇总」这个工具函数举例,测试会把各种边界情况都钉死:
describe('summarizeToday 今日汇总', () => {
it('空记录返回零值', () => {
expect(summarizeToday([])).toEqual({ feed: 0, sleep: 0, diaper: 0 })
})
it('补记的记录计入昨天', () => {
// 晚于当前时间的喂奶自动归昨天补记
const rec = [{ type: 'feed', time: '昨天 23:50', retro: true }]
expect(summarizeToday(rec).retroCount).toBe(1)
})
it('跨天睡眠拆分到对应日期', () => {
// 23:00 睡到次日 02:00,要拆成两段
})
})
这些「空记录」「补记归昨天」「跨天拆分」,全是真实业务里踩过或预判的边界。把它们写进测试,AI 实现时就必须处理,漏一个测试就红。
五、给想用 AI 写代码的你三条建议
- 别让 AI 裸奔。没有测试的 AI 代码,等于没有刹车的快车。先搭测试框架再谈功能。
- 流程比提示词重要。spec→plan→TDD 这套流程,比「怎么写好一句 prompt」值钱得多------它管的是不乱,不是快。
- 测试跟着功能长。别想着最后一起补,那时候你已经不知道哪些地方该测了。每加一个功能,先把它的测试写完。
AI 让「写代码」这件事变廉价了,但「保证代码对」这件事的价值反而变高了。TDD 就是把后者兜住的那张网。
如果这篇对你有用,欢迎关注 看「AI 工具人 PM 实战」系列更新;你用 AI 写代码时靠什么保证它没写错,评论 聊聊;觉得有用就收藏备用。
下一篇预告:《AI 时代产品经理的核心价值:三个被我自己推翻的功能决策》------讲讲我亲手砍掉一个已完成功能的经过。