• 正文
  • 相关推荐
申请入驻 产业图谱

嵌入式+AI做测试驱动开发TDD实战

9小时前
128
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

TDD:测试驱动开发,分为三个阶段,红灯阶段,绿灯阶段,重构阶段。

几年前第一次接触 TDD 。当时在一个项目里被强制要求"先写测试 再写代码"。坚持了三个月,最后整个团队默契地放弃——因为太慢了。同样一个功能,先写测试要多花 50%-80% 的时间,老板看不到产出,我们自己也累。

后来我基本没再认真做过 TDD。偶尔有人提我都翻白眼:"那玩意儿在真实业务里跑不起来。"

直到 2025 年下半年开始重度用 Claude / Cursor 做嵌入式开发,我意外地把 TDD 用回来了——而且这次是真心觉得好用。今天写一下为什么。

预警:本文不是给你布道 TDD。是讲当 AI 进入工作流后,TDD 的成本结构发生了根本变化,原来不划算的事现在划算了。如果你跟我十年前一样讨厌 TDD,强烈建议看完。

一、传统 TDD 为什么大多数人坚持不下来

经典 TDD 流程:

1. 写一个失败的测试(Red)
2. 写最少代码让测试通过(Green)
3. 重构(Refactor)
4. 回到 1

理论上完美——实际三个痛点:

痛点 1:写测试比写功能还累

要测试一个 parseConfig(yaml) 函数,你得:

    想清楚 N 种输入(合法 / 非法 / 边界 / 极端)给每种输入构造 fixture写 assertion跑通

往往测试代码 200 行,功能代码 50 行。开发团队心理上接受不了。

痛点 2:需求变化让测试变成债务

需求改了,功能代码改 5 行,测试代码要改 50 行——不然全红。很多团队最后选择"先改功能、测试坏了删掉"。删着删着 TDD 就名存实亡。

痛点 3:很多代码"难测试"

UI、硬件交互、第三方 API、复杂时序——这些代码写测试比写功能难 10 倍。嵌入式领域尤其严重,一个驱动函数依赖寄存器 / 时钟 / 中断,纯软件 mock 几乎不可能。

痛点 4:测试质量难保证

测试写得烂的话——比如只测 happy path、断言空泛——还不如不写。给团队"我们有测试"的虚假安全感。而写好测试需要的技能跟写好功能一样难

这四个痛点叠加,使 TDD 在实际项目里理论上正确、实际上跑不起来


二、AI 改变了什么

四个痛点里,AI 直接打掉三个

痛点 1 → AI 让"写测试"变得几乎免费

让 Claude 给一个函数生成一组完整测试用例——30 秒。覆盖度比你手写还高(AI 见过更多 edge case)。

写测试的成本从"高于功能"变成"低于功能"。TDD 的最大经济障碍消失

痛点 2 → AI 让"维护测试"变得便宜

需求变了,原来要手改 50 行测试。现在 prompt:

功能签名从 X 变成 Y,请同步更新这组测试。

AI 30 秒搞定。我手动 review 5 分钟。测试维护成本降一个数量级

痛点 3 → AI 让"难测代码"变得能测

嵌入式驱动测试难在"mock 硬件"。让 AI 帮你写:

基于这份 datasheet 的 register map,给我一个 mock 寄存器层,能模拟以下行为:
- 写入 0x01 到 CTRL → STATUS 在 100us 后变成 0x80
- 读 DATA 寄存器返回上次设的 value
- ...

AI 给的 mock 层 200-500 行,你手写要 1-2 天

痛点 4 → AI 让"测试质量"有保障

让 AI review 你的测试:

这组测试覆盖了哪些场景?哪些边界 case 缺失?
- 空输入
- 极大值
- 并发
- 错误注入
- 类型异常

AI 列出来你查漏补缺。测试质量从依赖个人经验变成有兜底


三、AI-TDD 工作流(我的实操版本)

放弃经典三步循环,我现在的工作流是这样:

Phase 1: 跟 AI 对齐意图(5-10 min)
   ↓
Phase 2: AI 生成测试套件(5-10 min)
   ↓
Phase 3: 人工 review 测试(10-15 min)  ← 关键
   ↓
Phase 4: AI 实现功能(5-15 min)
   ↓
Phase 5: 跑测试 → 红 → 让 AI 修
   ↓
Phase 6: 全绿后做边界扩展

下面分阶段讲。


四、Phase 1:跟 AI 对齐意图

不要直接说"写一个 parseConfig 函数"——那是 1990 年代的需求传达方式。

正确做法是写 spec

我要实现一个 YAML config parser。

输入:YAML 字符串
输出:Config 结构体 / 错误

【字段】
- name: string, required, 1-64 字符, 只能字母数字 _ -
- port: int, required, 1-65535
- timeout_ms: int, optional, default 5000, 范围 100-60000
- backends: list of {host, port}, required, 至少 1 个
- tls: nested object, optional
  - cert_path: string, 文件必须存在
  - key_path: string, 文件必须存在
  - ca_path: string, optional

【错误处理】
- YAML 语法错误 → ParseError,含行列号
- 字段缺失 → ValidationError("missing field: <name>")
- 字段类型错 → ValidationError("invalid type for <name>: expected X got Y")
- 范围 / 格式错 → ValidationError("invalid value for <name>: ...")
- 文件不存在 → ValidationError("file not found: <path>")

【约束】
- 不允许未知字段(strict mode)
- 数字字段不接受字符串
- 路径用 forward slash 统一

这份 spec 有 30 行——以前我直接写代码可能 3 行需求注释。但这 30 行就是后面所有测试和代码的契约

写 spec 比写代码难——但这件事 AI 也能帮你

我要做个 YAML config parser,主要字段是 name / port / backends。
请帮我列出一份完整 spec:
- 该有哪些字段
- 每个字段的约束(类型 / 范围 / 格式 / required)
- 错误处理策略
- 边界情况
让我能基于这份 spec 写测试。

AI 给完,你 review 增删——人 + AI 的对齐过程,本身就是需求澄清


五、Phase 2:AI 生成测试套件

把 spec 给 AI:

基于这份 spec:
<贴 spec>

写一个完整的测试套件。要求:
1. 用 pytest
2. 每个字段的 happy path + 至少 3 个 error case
3. 嵌套 / 组合场景至少 5 个
4. 边界值(min / max / max+1 / min-1)
5. 类型错误(每个字段给一个错误类型)
6. 一组真实业务场景的 fixture(YAML 字符串放 fixtures/ 目录下)
7. 测试命名清晰:test_<scenario>_<expected>
8. 失败信息要包含 "实际值 vs 期望值"
9. 用 parametrize 减少重复

AI 一般给 30-80 个测试,800-2000 行。

我做过的真实项目里,spec 30 行 → 测试 1500 行。手写要 2 天,AI 给完 + review 半天


六、Phase 3:人工 review 测试(最关键)

这一步不能跳。AI 生成的测试质量参差,必须人工把关。

review 的几个重点:

6.1 断言方向是否对

AI 经常会写:

assert result.port == 8080  # 实际期望是 8081

或者更隐蔽的:

assert err is not None  # 应该是 isinstance(err, ValidationError)

断言写错 = 测试在保护错误的行为。很危险

6.2 测试是否真的会失败

让 AI 故意把功能代码写错一行,跑测试——应该红的测试有没有红

很多 AI 写的测试 mock 太多,导致功能代码怎么写都过。这种"绿色"测试比没有还糟。

6.3 边界 case 是否真的边界

AI 会写:

def test_port_max():
    assert parse({"port": 65535}).port == 65535

def test_port_max_plus_1():
    with pytest.raises(ValidationError):
        parse({"port": 65536})

OK。但它会漏 0、负数、浮点数、字符串、None——这些都得加。

6.4 测试代码自己有没有 bug

AI 写的 fixture 经常有 typo / 不一致。例如:

yaml_data = """
name: test
port: 8080
backens:  # ← typo: backends
  - host: localhost
"""

这种 fixture 让测试结果完全错乱——它在测"backends 缺失",但你以为它在测"backends 配置正常"。

review 测试的时间投入大约是 AI 生成时间的 2-3 倍——这是 AI-TDD 里最贵的环节,不能省


七、Phase 4:AI 实现功能

测试 review 通过后,让 AI 写实现:

这是测试套件:
<贴测试代码>

请实现 parse_config 函数让所有测试通过。

要求:
1. 不要在测试上动手脚(不许改测试让自己过)
2. 如果某个测试设计本身有问题,先告诉我,我决定要不要改
3. 实现风格:纯函数 / 不依赖全局状态
4. 用 ruamel.yaml 解析(保留 yaml 1.2 语义)
5. 错误信息要 actionable

关键 prompt:"不要在测试上动手脚"——AI 真的会改测试让自己过。我有过几次它默默把 assert x == 5 改成 assert x == 4,因为它实现里返回了 4。

跑测试,看红的有几个。


八、Phase 5:让 AI 修

这些测试红了:
<贴 pytest output>

请:
1. 分析每个失败原因
2. 修改实现(不是测试)
3. 如果你发现某测试期望可能写错了,单独标出来给我决定

通常 1-3 轮就能全绿。

我做过的项目里,AI 一次实现就全绿的概率约 40%。1 轮修复后绿的约 80%。3 轮还修不好的约 5%——这种通常是 spec 本身有歧义,要回 Phase 1 重新对齐。


九、Phase 6:边界扩展

全绿了不是结束。让 AI 帮你找还没测的角落

基于以下功能代码 + 测试:
<贴代码 + 测试>

请:
1. 找出尚未覆盖的 code path(用 coverage 思路分析)
2. 找出可能的 race condition / 并发问题
3. 找出依赖外部状态(文件 / 环境变量 / 时间)的部分,建议补充对应 mock 测试
4. 找出错误处理路径中没被触发的分支
5. 给出补充测试代码

AI 经常找出 5-15 个补充测试。我加上去再跑——通常会发现 1-3 个真 bug。

pytest --cov=parse_config --cov-report=term-missing

跑 coverage 看实际覆盖。覆盖到 95%+ 才算 done。


十、跟传统 TDD 的对比(真实数字)

我对一个中等复杂度的功能(约 300 行实现)做过三种方式对比:

方式 实现耗时 测试覆盖率 上线后 bug
不写测试,直接撸代码 4h 0% 上线第一周 5 个 bug
传统 TDD(手写) 14h 65% 上线第一周 2 个 bug
AI-TDD 6h 92% 上线第一周 0 个 bug

AI-TDD 比"直接撸"只多 50% 时间,但 bug 数从 5 → 0。比传统 TDD 时间少 60%、覆盖率高 27%。

AI-TDD 是目前性价比最高的开发方式


十一、什么场景特别适合 AI-TDD

1. 纯函数 / 数据处理

输入 → 输出 没副作用的函数。AI 最强场景。

2. parser / serializer / validator

边界 case 多但模式清晰。AI 生成测试覆盖度极高。

3. 状态机

每个 state transition 都该有测试。AI 能枚举完整 transition。

4. API contract

接口的 happy path + error path + auth path。AI 套路化生成。

5. 算法实现

排序 / 搜索 / 数学函数。AI 生成的测试比 leetcode 题库还全。

6. 嵌入式驱动(带 mock 寄存器层)

参考之前写的硬件自动化测试。AI 帮你 mock 硬件后,驱动也能 TDD。


十二、什么场景不适合

1. UI 交互逻辑

AI 测试可以做单元,但用户体验类的东西测试无意义。靠人工 + E2E。

2. 性能优化代码

性能 bug 不在功能正确性。性能测试要专门的 benchmark,不是 TDD。

3. 探索性原型

你都不知道最终要什么——写 spec 写不出来。先撸代码再补测试。

4. 一次性脚本

跑完就扔,TDD 投入回不来。

5. 跟物理世界强耦合

机器人控制、模拟仿真——mock 失真度太大,测过不代表实际能跑。

6. AI / ML 模型本身

模型行为是统计性的,不是确定性的。"测试"要换成"评估指标"——是另一套体系。


十三、经验

1. spec 阶段花的时间不是浪费

很多人觉得"写 30 行 spec 还不如写代码"——但 spec 是后面所有 AI 工作的种子。spec 越精确,AI 后面越准

我现在写 spec 平均花 15-20 分钟。这是整个流程里"投入产出比最高"的 15 分钟。

2. 不要让 AI 同时写测试和实现

我试过"一次给 spec,让 AI 同时给测试 + 实现"——结果AI 会让自己的测试测自己的实现,循环自洽但实际错的

必须先生成测试 → 人 review → 再生成实现。两步分开,有人工把关在中间。

3. test-only commit + impl commit 分开

git 历史里把"加测试"和"加实现"做成两个 commit。这样 review 容易:

    commit 1: "Add tests for parse_config" — reviewer 关注 spec / 测试设计commit 2: "Implement parse_config" — reviewer 关注实现细节

也方便后续:如果实现改了,可以 revert impl commit 但保留测试。

4. 测试 + 实现都用 AI 生成不会让你失业

很多人怕"AI 都能写测试 + 实现了,要工程师干嘛"。

真相:AI 接管的是"机械劳动",留给你的是"判断"——

    spec 写得对不对测试设计合不合理边界 case 漏没漏实现风格符不符合团队维护成本可不可控

这些判断全是经验性工作——新人做不来。AI 时代的高级工程师价值更高,不是更低。

5. CI 必须跑 100% 测试 + coverage 阈值

AI-TDD 的代码量大、测试量更大——必须 CI 强制跑:

test:
  script:
    - pytest --cov=src --cov-fail-under=85

低于 85% 覆盖直接 fail。这是防止"AI 写的代码 + AI 写的测试 + 没人看 = 灾难"的最后一道防线

6. 留一类"人工写的整合测试"

单元测试 AI 写。但端到端 / 集成测试坚持人工写——这种测试反映"真实业务流",AI 不知道你们公司的真实业务长什么样。

规则:单元测试 AI 写 90%,集成测试人工写 90%。


十四、AI-TDD 的盲区和风险

1. AI 测试的"思维定式"

AI 见过的测试模式有限。某些罕见 case(如"内存对齐边界 + 大端字节序 + 跨页访问")AI 不会想到。

对策:补充测试时多用"如果是攻击者,他会怎么打"的视角,AI 给不出,你自己想。

2. 测试 + 实现一起飘

AI 看测试写实现 → 发现某测试难过 → 偷偷改测试 → 你没注意 → 测试和实现一起偏离 spec。

对策:每次让 AI 改代码后,diff 看测试文件有没有变。变了要警惕。

3. 过度测试

AI 倾向"写更多测试"——一个简单函数给你 100 个测试。真的有用的可能 30 个。剩下 70 个增加维护成本但不增加保障。

对策:review 时主动删除"测同一行为不同写法"的重复测试。

4. spec 漂移

迭代过程中需求变了,spec 没同步更新。AI 接着按老 spec 改 → 一致性破坏。

对策:spec 文档跟代码放一起(同 repo),改需求 = 改 spec + 改测试 + 改实现的 atomic commit。

5. 安全敏感代码不能完全信 AI

加密 / 鉴权 / 输入校验 / 反序列化——AI 写的实现可能"测试都过但有 CVE"。

对策:这类代码强制人工 review 实现 + 加 fuzz testing 不只是单元测试。


十五、ROI 排序:哪些场景立刻能上 AI-TDD

立刻就上(一天见效)

新写的纯函数:parser / validator / formatter / converter

现有函数的 bug fix:先写复现 bug 的测试,再让 AI 修

一周内试一次

新模块的 API 层:路由 + handler + validator

现有模块的重构:先用 AI 补一波测试,再放心重构

一个月内推广

全团队 spec-first 流程:所有 PR 必带 spec + 测试

CI 集成 coverage gate

谨慎对待

遗留代码补测试:先补集成测试,单元测试可能没意义

跨服务集成:mock 不到位时 TDD 是假的


十六、写在最后

AI 把 TDD 里"贵的部分"变便宜了:

    写测试 → 免费维护测试 → 免费mock 难测代码 → 免费找漏掉的 case → 免费

留给人做的是判断:spec 对不对、测试设计合不合理、bug 是不是真 bug。这部分本来就是工程师该做的事

如果你跟十年前的我一样觉得 TDD 是大忽悠——今天找一个新写的纯函数,按本文 6 步走一遍。一个小时之内你会改主意。

如果你已经在用 AI 写代码但还没用 AI-TDD——你少拿了一半 AI 的红利。AI 写完代码不写测试 = 你在生产环境裸奔。

最后一个观点:未来 2-3 年,"会做 AI-TDD" 会跟"会用 git"一样,是行业基础技能。早点上手,早点习惯。

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

研究生在读,熟悉硬件、STM32单片机、嵌入式Linux。已收获小米、联发科、浙江大华、上能电气、英威腾、汇川技术、格力、富士康等大厂offer。在这里分享求职经验、嵌入式学习规划、考研、嵌入式Linux技术文章等。