别手写断言了!Copilot for Testing 让我提前两小时下班

3 阅读8分钟

上周三下午四点半,我正在收拾包准备去接孩子,隔壁工位的老王探过头来:“你今天咋跑这么早?版本不是明天封板吗?”

我指了指屏幕上的测试报告:“跑完了,全过,断言也写完了。”

老王愣了一下:“断言写完了?我记得你上午还在说有个订单状态的接口要写20多个断言场景……”

我笑了:“是啊,但是下午一个都没手写。”

这话听起来像吹牛,但其实我只是换了个玩法——把写断言这件事,交给了Copilot。

一、断言这东西,写多了烦,写少了慌

先说说背景。我们团队做接口自动化,用的Python + pytest,平时最烦的就是写断言。

你说接口调通了没?调通了。但是调通不等于测完啊。

  • 返回的JSON里有个字段叫“status”,是等于“SUCCESS”还是“200”?得断言。
  • 下单接口返回的订单号,格式是不是符合规则?得断言。
  • 分页查询返回的总条数,对不对得上数据库?得断言。
  • 异常场景下返回的错误码,是不是我们预期的那几个?也得断言。

一个接口下来,少则三五个断言,多则十几个。而且很多断言长得都差不多——assert response.json()["code"] == 200,assert response.json()["data"]["status"] == "SUCCESS"——写的时候手指头都麻了。

更要命的是,有时候忙晕了,写完脚本一跑,全绿,以为万事大吉。结果上线后发现有个字段返回null,脚本里根本没断言这个字段——它不报错,但它不代表业务正常。这就是论坛里说的“缺失断言”陷阱。

上个月就有这么一回,一个优惠券接口返回了错误的面额,但因为脚本里只断言了状态码,没断言金额字段,这bug愣是混到预发环境才被发现。从那之后我就想,能不能找个办法,让AI帮我把该断言的都补上?

二、从“跑通”到“测对”,就差一个AI

这周我开始认真试Copilot,目标很明确——让它帮我写断言

最开始是简单粗暴型。写一个接口请求,然后在下面空一行,打注释:

# 断言登录成功

Copilot直接给我补了三行:

assert response.status_code == 200
assert response.json()["code"] == 0
assert response.json()["message"] == "登录成功"

我一看,行啊,这基本套路它懂。

再试复杂点的:

# 断言返回的订单列表包含刚创建的那个订单ID

Copilot想了想,给我补了这么一段:

order_ids = [order["id"] for order in response.json()["data"]["orders"]]
assert new_order_id in order_ids, f"新订单ID {new_order_id} 不在返回列表中"

连错误信息都帮我写好了。

试了几次之后,我琢磨出点门道:Copilot写断言,靠的是上下文理解。它看到你前面发了请求,知道返回是个JSON,再结合注释里的意图,就能推断出你要断言什么。

但有个问题——它有时候不知道你要断言什么。比如你只写“断言接口返回”,它可能给你生成一堆冗余断言,连没啥意义的时间戳都给你断言上。这时候就得靠“引导”。

三、怎么“教”AI写出靠谱的断言?

这一周我总结了几种让AI写断言靠谱的方法,分享给可能用得上的同学:

方法一:用自然语言描述意图

别只写“断言”,要写清楚断言什么。比如:

# 断言返回的优惠券金额等于100元

或者更细一点:

# 断言错误场景下返回400状态码,且error字段包含"余额不足"

Copilot会根据你的描述,生成对应的断言代码。描述得越具体,生成得越准。

方法二:给个例子让它照着写

有时候接口返回结构比较复杂,比如嵌套好几层的JSON。这时候我会先手写一个断言的例子,然后在下面写注释“类似上面,断言其他字段”。

比如:

# 示例:断言用户ID正确
assert response.json()["data"]["user"]["id"] == expected_user_id

# 类似上面,断言用户名称和邮箱

Copilot会模仿你的写法,自动补全剩下的。

方法三:让AI补全“缺失的断言”

这是我觉得最有用的功能——把脚本写完,让AI检查哪里没断言

我试过写完一个下单接口的脚本,然后注释一行:

# 检查这个测试用例还有哪些关键字段没断言

Copilot扫描了一遍代码,然后提示我:

  • 未断言订单金额
  • 未断言支付状态
  • 未断言返回的订单号格式

然后逐行帮我补上了对应的断言。

这种感觉挺神奇的——好像有人在Code Review你的测试脚本,告诉你哪里漏了。

四、两个进阶玩法,让断言真正“聪明”

除了基本的“补断言”,这一周我还试了两种进阶玩法,效果超出预期。

玩法一:让AI生成“多断言”组合

有个学术研究提到,超过40%的测试用例其实包含多个断言,但传统工具往往只生成单个。Copilot在这点上做得不错。

比如测一个订单查询接口,我需要断言三件事:

  1. 状态码200
  2. 返回的订单数量正确
  3. 订单列表按时间倒序排列

以前我得手写三行。现在直接写注释:

# 断言查询成功、返回10条订单、且按时间倒序排列

Copilot生成的代码:

assert response.status_code == 200
data = response.json()["data"]
assert len(data["orders"]) == 10
assert data["orders"] == sorted(data["orders"], key=lambda x: x["createTime"], reverse=True)

三个断言一次搞定。

玩法二:让AI做“语义断言”

这是我从飞猪那篇文章里看到的思路——传统的断言只能校验字段值,但AI可以校验“语义”。

举个例子,测一个智能客服接口,返回的是自然语言回答。你用传统断言没法写——因为回答每次都不一样。但用AI可以这样:

# 断言回答包含了用户咨询的订单号

Copilot会生成一个用NLP库做语义检查的代码,比如用fuzz.partial_ratio或者直接调一个文本匹配函数。

更高级的,可以结合RAG(检索增强生成),让AI去知识库里查“正确的回答应该长什么样”,然后自动比对。这已经超出普通断言的范围了,叫“智能校验”可能更合适。

五、两天试用下来,我的感受

从周二开始试,到今天周四,两天时间我写了大概30多个接口的测试脚本。对比之前手写,有几个直观变化:

1. 快。写断言的速度至少快了3倍。以前写一个接口要15分钟,现在5分钟搞定。今天下午4点收工,比平时早了两小时。

2. 全。有个登录接口,我自己写只断言了code和message,Copilot帮我补了token字段非空、token格式、过期时间——这些我压根没想到要断言的。

3. 稳。以前写断言,最怕那种“断言了但没断言对”的情况——比如字段名拼错了、路径写深了一层。Copilot生成的代码基本不会犯这种低级错误。

当然也有坑。有一次它给我断言了一个根本不存在的字段,可能是被别的项目带偏了。所以我现在跑之前还是会扫一眼代码,确认它没瞎写。

六、要是能把这个推给全团队……

今天老王问我怎么做到的,我给他演示了一遍:

  • 先写接口请求
  • 然后打注释描述要断言什么
  • Copilot自动补全代码
  • 跑一下,绿了,收工

他看完沉默了十秒,然后说:“这东西能教会我不?”

我说当然能。其实门槛很低——只要会写注释,就能让AI帮你写断言。

我甚至想,如果团队能建一个“断言知识库”,把常见的业务规则、字段校验逻辑都存进去,再让AI去检索、学习,那以后写断言可能真的不用动手了。


关于我们

霍格沃兹测试开发学社,隶属于 测吧(北京)科技有限公司,是一个面向软件测试爱好者的技术交流社区。

学社围绕现代软件测试工程体系展开,内容涵盖软件测试入门、自动化测试、性能测试、接口测试、测试开发、全栈测试,以及人工智能测试与 AI 在测试工程中的应用实践。

我们关注测试工程能力的系统化建设,包括 Python 自动化测试、Java 自动化测试、Web 与 App 自动化、持续集成与质量体系建设,同时探索 AI 驱动的测试设计、用例生成、自动化执行与质量分析方法,沉淀可复用、可落地的测试开发工程经验。

在技术社区与工程实践之外,学社还参与测试工程人才培养体系建设,面向高校提供测试实训平台与实践支持,组织开展 “火焰杯” 软件测试相关技术赛事,并探索以能力为导向的人才培养模式,包括高校学员先学习、就业后付款的实践路径。

同时,学社结合真实行业需求,为在职测试工程师与高潜学员提供名企大厂 1v1 私教服务,用于个性化能力提升与工程实践指导。