测试驱动开发 (TDD) 新解法:AI 帮你写 Unit Test

2025-12-02 11:05:19
文章摘要
今天我们要用 ChatGPT 和 文心一言 当我们的“测试外包团队”。我不教你枯燥的断言语法,我教你如何让 AI 在 30 秒内帮你搞定 100% 覆盖率 和 魔鬼级边界测试。

作者:小招 | 栏目:程序员 AI 提效指南


前言:从“不得不写”到“躺着写”

大家好,我是小招。如果把写代码比作“生孩子”,那写单元测试(Unit Test)绝对是“带孩子”——既繁琐又磨人,但为了不让孩子(代码)长歪,你又不得不做。

大家都知道 TDD (Test-Driven Development,测试驱动开发) 是好东西,它能降低 Bug 率,利于重构。但为什么 90% 的程序员坚持不下来?因为太慢了。写业务逻辑 5 分钟,写测试用例半小时,谁顶得住?但在 AI 时代,这个逻辑变了。

今天我们要用 ChatGPT文心一言 当我们的“测试外包团队”。我不教你枯燥的断言语法,我教你如何让 AI 在 30 秒内帮你搞定 100% 覆盖率魔鬼级边界测试


01. 基础篇:快乐路径 (Happy Path) 的极速生成

先说最简单的场景。假设你刚写好了一个工具函数,或者按照 TDD 的思路,你刚定义好接口。

以前你需要手动引入 JUnitJest,然后一行行敲 expect(result).toBe(true)。现在,你只需要把代码扔给 AI。

推荐工具

  • ChatGPT-4o:逻辑最严密,适合生成复杂的 Mock。
  • 文心一言 4.0:对中文业务文档理解好,生成 Java/Python 代码非常标准。

Prompt 模板:

Role: Senior QA Engineer
Tech Stack: TypeScript + Jest (或者 Java + JUnit 5)

我提供一段业务代码(或接口定义),请你完成以下任务:

  1. 为我生成标准的单元测试代码。
  2. 包含 3 个基础的“快乐路径”测试用例(即正常输入下的预期结果)。
  3. 使用 Describe 和 It 结构清晰组织。

[粘贴你的代码片段]

小招 Tip:不要只贴代码,一定要指定测试框架(如 Jest, PyTest, JUnit)。否则 AI 可能会给你随机生成一个你项目里根本没装的库。

图片描述

  • 图注: ChatGPT 生成的包含 describebeforeEach 和 3 个标准 test case 的完整代码块。

02. 进阶篇:边界条件 (Edge Cases) —— AI 比你更像魔鬼

写测试最难的不是测“正常情况”,而是测“异常情况”。

  • 用户输入了负数怎么办?
  • 用户输入了 Emoji 表情怎么办?
  • 日期是闰年 2 月 29 日怎么办?

作为开发者,我们很容易陷入思维盲区,觉得“用户不会这么蠢”。但 AI 没有这种偏见,它能模拟出最刁钻的用户。

寻找漏洞 Prompt 模板:

请扮演一个喜欢找茬的黑客或苛刻的测试经理。
针对上述代码,请列出至少 5 个可能导致崩溃的“边界条件”或“极端情况”,并为它们编写对应的测试用例。

关注点包括但不限于:Null/Undefined、空字符串、超大数值、特殊字符、并发调用。

你会惊讶地发现,文心一言或 ChatGPT 会生成诸如 test("输入包含 10MB 的字符串时应抛出异常") 这样的用例。这些往往是你生产环境 Bug 的源头。 可能导致崩溃的边界条件 / 极端情况(至少 5 个)

序号 极端情况 为什么危险?
1 price = nulldiscountPercentage = null JS 数值运算中 null 会变成 0,但属于隐性错误
2 undefined 作为参数 会导致 undefined / 100 = NaN,返回 NaN
3 非数字(如 '100', 'abc', 特殊字符) 隐式转换会导致 NaN 或意外行为
4 超大数值(如 Number.MAX_SAFE_INTEGER 可能导致精度丢失或溢出
5 NaN 参数 所有计算都变成 NaN
6 多线程并发(在 Node 中用 Promise.all 模拟) 如果函数不是纯函数,可能产生竞态;此处可验证纯函数无共享状态
7 Negative price(负价格) 业务语义不合理,但不会被当前逻辑拦截
  • 图注:展示 AI 列出的测试点:1. 空数组输入;2. 负数金额;3. SQL 注入字符;4. 2038 年时间戳溢出问题。这些是人类容易忽略的盲区。

03. 高阶篇:搞定最难的 Mock 与 Stub

单元测试最让人头秃的,就是代码里调用了数据库外部 API 或者 Redis。我们不能真去连库,必须 Mock(模拟)。

手写 Mock 代码非常痛苦:jest.spyOn, Mockito.when... 语法又长又难记。这正是 AI 擅长的领域。

Mock 生成 Prompt 模板:

我的代码中调用了 `UserService.getUserById()` 和 `PaymentGateway.charge()`。
请帮我编写测试代码,要求:
1. Mock 掉这两个外部依赖,不要发起真实网络请求。
2. 模拟 UserService 返回成功和失败两种情况。
3. 验证当 PaymentGateway 抛出 TimeoutException 时,我的代码是否正确处理了回滚逻辑。

AI 会自动帮你写好 Mockito 的配置或者 Python 的 @patch 装饰器。你只需要把代码复制进去,运行,全绿。


04. 终极目标:冲击 100% 覆盖率

虽然小招常说“过分追求 100% 覆盖率是虚荣指标”,但在核心模块(如计费、权限),100% 是必须的。

如何填补最后的 5% 空缺?让 AI 帮你做“填空题”。

实操步骤:

  1. 在本地运行测试,生成覆盖率报告(Coverage Report)。
  2. 找到那些红色的、未覆盖的代码行。
  3. 把这些行复制给 AI。

查漏补缺 Prompt 模板:

我的单元测试覆盖率目前是 92%。
以下代码行没有被覆盖到:
[粘贴未覆盖的代码逻辑,例如 catch (e) { log.error(e) }]

请帮我补写一个特定的测试用例,专门触发这个分支逻辑,从而让覆盖率达到 100%。

AI 会告诉你:“哦,你需要模拟一个数据库连接断开的异常,才能走到这一行 Catch 代码。”并直接给出代码。


小招总结

TDD 在过去是一种“奢侈品”,因为太费时间;但在 AI 时代,TDD 变成了“必需品”。

因为 AI 写的代码(Copilot 生成的)有时候会包含幻觉,我们需要 AI 写的测试(ChatGPT 生成的)来验证 AI 写的代码。用魔法打败魔法,这才是闭环。

今日实操清单:

  1. 打开你的 ChatGPT 或 文心一言。
  2. 复制一个你最近写的函数。
  3. 输入命令:“你现在是测试专家,请帮我把这个函数的单元测试写满,我要 100% 覆盖。”

你会体验到那种看着控制台一路绿灯(All Tests Passed)的多巴胺分泌快感。

下期预告: 测试写完了,代码上线前还得过一关——《代码审查 (Code Review) 自动化:让 AI 做你的第一道防线》。关注小招,让你的代码无懈可击。


(本文工具建议:生成 Mock 代码推荐使用 ChatGPT-4o,中文业务逻辑理解推荐文心一言 4.0)

声明:该内容由作者自行发布,观点内容仅供参考,不代表平台立场;如有侵权,请联系平台删除。