最近团队里掀起一股“AI写用例”的风潮,说实话,我看着有点着急。产品经理拿着ChatGPT生成的几十条用例眉飞色舞,开发兄弟也觉得自己能一键覆盖所有场景了。但我不得不泼盆冷水:绝大多数AI生成的测试用例,如果不注入一种核心思维,本质上就是一堆格式精美的废纸。
上个月,我用某个新上线的支付网关接口做过实验。让大模型根据接口文档生成了整整180条用例,乍一看,等价类、边界值、异常参数全覆盖,评审时实习生眼睛都在发光。我没多说,只随手抽出一条“支付金额为负数应失败”的用例,问了三个问题:
如果我在回调极高频次下,连续发起两笔金额相同的负数支付,幂等性控制会不会被绕过?
这条用例的数据库锁是行锁还是表锁?在跨库事务里会不会产生死锁?
假如上游系统正好在这个负数请求超时后发起重试,冲正逻辑是否能正确识别“已失败”状态而不造成资金挂账?
会议室安静了。这就是问题的核心:AI能穷举所有你“知道”的测试点,却完全无法触达那些你“没想到”的风险。 这之间的差距,我管它叫“攻击性测试思维”。
为什么你的AI用例发现不了Bug?
很多团队把AI生成的用例视作银弹,是因为他们误解了测试的本质。测试不是“证明软件按预期工作”,那是验收。测试的本质是“用结构化的破坏行为,尽可能早地暴露系统脆弱点”。
AI非常擅长完成第一种任务。你喂给它一份接口协议,它能瞬间完成字段拆分、边界值计算、必填项组合。但它生成的用例带着一股浓重的“学生作业”味道——完美符合规范,却对真实世界的混乱毫无准备。
举个真实的线上故障案例:一个物流追踪服务,AI生成的用例覆盖了所有快递状态流转的合法性。结果上线后,仅仅因为一个物流商推送的轨迹时间戳比当前服务器时间快了2秒,就导致状态机卡死,全网包裹停止更新。没有任何一条AI用例教会我们怀疑“时间”。因为它从文档里学不到:时间是不可信的,第三方的序列号会重复,内存会在高并发下悄悄翻转。
这种对“不可信”的深刻执念,就是攻击性思维的第一块基石。
缺少的核心思维:“攻击性场景建模”
我给团队做内训时,把这种思维拆解成一套可训练的模式,叫“攻击性场景建模”。它要求你暂时忘记“功能怎么用”,转而思考“这东西怎么才能坏”。它由三个问题驱动:
信任边界在哪? —— 凡是跨进程、跨服务、跨时钟、跨第三方数据的地方,都是信任边界。AI假设一切输入最终会符合契约,而你必须假设每条边界上都站着一个恶意的“骗子”。
什么约束是“隐式”的? —— 代码看得见的约束,if-else都处理了。但隐式约束呢?比如“回调一定比查询先到”“这条缓存key永远存在”“用户不可能在支付回调前一秒注销账户”。AI读不出这些假设,只有人才能嗅出这些藏在潜意识里的潜规则。
怎样用最小的代价制造级联失效? —— 不是简单地把某个服务打挂,而是让它在“半死不活”的状态下污染其他模块。比如让一个HTTP请求恰好卡在超时阈值上,把线程池撑满又不立即释放,看上游的熔断策略是否误判。
这三点,AI目前学不会。因为大模型的训练数据里,只有修复后的代码和正常流程的文档,极少有人把那些丑陋的、偶然的、令人难堪的生产事故喂给它。
三步把“废纸”变成探测利剑
我完全不是要否定AI工具,我自己每天在用。关键在于流程上,把AI生成的用例当作一堆质量良好的“砖头”,而攻击性思维就是盖房子的图纸。你可以试试这个我反复打磨的三步法:
第一步:破坏性假设注入
拿到AI生成的用例集,不要直接评审。先组织一场15分钟的“破坏者站会”,拉上开发、架构师一起,只围绕一个主题:“如果我是攻击者,我会怎么玩弄这个功能?”
比如面对一个AI生成的“批量导入会员”用例,我们会写下:
上传一个10万行的Excel,其中第512行的某个单元格悄悄嵌入一个=cmd|’/C calc’!A0(公式注入)。
在文件流里插入一个文件名带../../../etc/passwd路径遍历的压缩包。
构造一个UTF-8和非标准字符集混编的文件,观察解析器是崩溃还是悄无声息地截断数据。
这些破坏性假设会迅速转化为针对安全、健壮性的补充用例,而AI之前生成的正常用例,则可以作为这些攻击操作之后的系统恢复验证。
第二步:四维场景穷举
我会在白板上画一个四象限图,横轴是“数据/时序”,纵轴是“内部/外部”。要求团队成员把每个原始用例扔进四个象限里拷问:
数据+内部:若数据库连接池在这条用例执行时恰好耗尽,回滚是否完整?
数据+外部:第三方返回的单号,在这条用例中途突然从数字变成字母,序列化会不会崩?
时序+内部:系统时间恰好在用例执行中被NTP服务回调了,超时判断会不会永久挂起?
时序+外部:回调与主动查询的竞态,会不会产生一笔既“成功”又“失败”的幽灵订单?
你会发现,AI原本给出的那180条用例,经过这四维一展开,会衍生出近40条高价值的反直觉用例。而且80%的致命缺陷,恰恰就藏在你最初觉得“不可能发生”的那个象限里。
第三步:风险驱动的优先级排序
经过上面两步,用例数量可能会再次膨胀。这时需要冷酷地进行基于风险的排序。我用的一个土办法叫“脆弱性乘数”:给每个新用例评估两个维度——业务冲击程度(1-5分)和发生概率(1-5分)。特别地,对于“信任边界”上发生的概率,无论多低都要在初始评分上强制+2,因为边界上的“意外”永远比你预估的高一个数量级。
最终,保留那些高风险、高业务冲击的用例,把AI生成的冗余正常流程用例大胆砍掉40%。你会发现剩下的用例集变得极具“攻击性”:它们直指架构缝隙、假设盲区和第三方的不确定行为。
结语
在华为做了十几年测试架构,我最大的感悟是:能自动化的终将被自动化,但判断“哪里该测”的智慧,才是测试人的护城河。 AI生成的用例不是没用,它是忠实的记录员,帮你把显性知识结构化。但它永远无法替代一个优秀的测试工程师,在盯着系统日志时,内心深处那一声警觉的:“等等,这个错不太对劲。”
下次,当你再看到AI吐出海量用例时,不妨先停下来,用攻击性的目光扫一遍。那些不会撒谎、不会紊乱、不会背叛的代码,在真实世界里,随时会因为一个微小的信任崩塌而全面溃败。你的用例,要做的不是歌颂完美,而是预演这场溃败,并确保系统能踉跄地站住。
把那堆废纸,变成你手里最锋利的Bug探测器吧。这事儿,AI真替不了你。
本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。