你让 Claude 给折扣函数写单元测试,它很快交出 5 个用例:正常价、零件、两件——全是开心路径。边界价、负数、货币精度、叠加券冲突一个没有。CI 绿得漂亮,线上第一周就出现四舍五入投诉。
表面覆盖来自「示例式测试」思维:模型优先演示用法,而不是攻击代码。你要把失败路径、边界与性质条件写进强制清单,并要求它先列风险再写测试。
直接结论
写单测提示词必须要求:先输出风险列表与等价类,再写测试;覆盖正常、边界、非法输入、幂等/重复、精度。禁止只生成快乐路径。测试名应说明场景,断言要精确到关键字段。
具体做法
贴上函数签名、业务规则与已知坑,不要只丢代码。
你是注重边界的测试工程师。请为下列函数设计单元测试({pytest/JUnit})。
代码与规则:
{粘贴}
强制过程:
1) 先列出等价类与风险(含精度、空值、非法枚举、并发/重复调用若相关)
2) 再写测试,映射到风险编号
3) 至少40%用例必须是失败路径或边界
4) 每个测试一个场景;断言具体值,不只 assertTrue
5) 指出哪些需要固件/假时钟,哪些是纯单测
禁止只写happy path。
生成后用覆盖率工具看分支,把未覆盖分支贴回让它补测。
对金额/时间单独要求属性测试或表驱动用例。
注意点
第一,测试里出现 sleep 或真网络,通常不是好单测,提示词要禁止。
第二,不要追求行覆盖率数字而堆重复用例,应追求风险覆盖。
第三,模型可能根据「它以为的需求」写断言,必须用你的规则校准。
把「风险清单先行」变成团队模板后,Claude 的测试会立刻厚实一截。代码评审时先看测试是否覆盖你最担心的三件事,而不是看用例数量。若函数复杂,先拆纯函数再测,比在一大坨过程代码上硬写单测更划算。
可直接套用的完整提示词
角色:资深测试工程师。 任务:风险驱动的单元测试设计与代码。 输入:被测代码、业务规则、已知线上事故。 输出:风险表 → 用例表 → 测试代码 → 仍测不到的缺口与建议重构点。 约束:失败路径占比达标;禁止无断言测试;金额用小数精确断言。
表面测试还有一个特征:断言只检查「不抛异常」。要求 Claude 断言返回值、副作用与错误类型。对会改数据库的代码,明确用事务回滚或测试库。把线上 bug 复现成测试名,是提升测试价值的最快路径。
测试生成后,让模型画一张「风险到用例」的映射表贴进 PR 描述,评审人一眼能看出覆盖策略,而不是被测试文件长度吓住或骗过。
当你把线上事故写进提示词,Claude 补的测试往往最值钱。让失败记忆进入仓库,比追求覆盖率百分比更实在。
对异步代码,明确要求测取消、超时与重试,这些最容易被表面测试漏掉。
表面单测常忽略异常消息与错误码。要求断言异常类型与关键消息片段,能锁住合约。对纯函数,表驱动测试(很多组输入输出)比复制粘贴五个相似用例更清晰,也可让 Claude 直接生成参数表。把「已知线上事故」写成第一条必测,是团队文化问题,提示词只是落实工具。
补充:若代码依赖当前时间,提示词写明使用可注入时钟;若依赖随机数,要求种子可控。这些不写,模型就会给你脆弱测试。脆弱测试不是太表面,就是太不稳定,两者都该拒收。