AI+Swagger:一键生成500条pytest接口用例

举报
霍格沃兹测试开发学社 发表于 2026/09/30 12:59:42 2026/09/30
【摘要】 87个接口,手工点测3天,AI跑完3小时——核心不是模型多强,是Swagger够干净大家好,我是某互联网公司的测试架构师。上个月,团队接了一个订单中台的回归测试。87个接口,前后端分离,Swagger文档写得整整齐齐。测试组长看了一眼排期,说了一句:“按老规矩,3天起步。”他说的“老规矩”,是用Postman手工点测。87个接口,每个接口测正常流、缺参、类型错、边界值、鉴权,一个接口平均6-...
87个接口,手工点测3天,AI跑完3小时——核心不是模型多强,是Swagger够干净

大家好,我是某互联网公司的测试架构师。

上个月,团队接了一个订单中台的回归测试。87个接口,前后端分离,Swagger文档写得整整齐齐。测试组长看了一眼排期,说了一句:“按老规矩,3天起步。”

他说的“老规矩”,是用Postman手工点测。87个接口,每个接口测正常流、缺参、类型错、边界值、鉴权,一个接口平均6-8条用例,加起来500多条。一个人点一遍,3天是乐观估计。

我说:“你让我用AI跑一遍试试。”

3小时后,CI上跑了529条pytest用例,全量回归通过。MR冒烟测试只要20分钟。

测试组长看完报告问了一句:“你怎么做到的?”

一、先别碰AI——把Swagger弄干净

这是整个流程里最容易被跳过、也最重要的一步。

我一开始也想着直接把Swagger文件喂给大模型,让它生成用例。结果AI生成了一堆不存在的字段——它把orderStatus写成了order_state,把amount的枚举值猜成了字符串数组。

后来我发现,问题不在AI,在Swagger本身。

我们要求每个接口必须满足五个条件:

  • OpenAPI 3.0,别拿Swagger 2.0凑合
  • operationId唯一,后面用例ID靠它
  • 每个schema字段尽量有example
  • 必填字段、枚举、最大最小长度写清楚
  • 错误响应别只写个400,把业务错误码也列出来

校验命令放在pre-commit里:

openapi-spec-validator openapi.yaml

这一步很枯燥,但省不掉。Swagger越像合同,后面生成的用例越像回事。

二、把接口抽成“用例原材料”

Swagger清洗干净了,下一步不是直接生成测试文件,而是先生成一份可人工审核的YAML。

我写了一个脚本,把OpenAPI里的operation拉平:

# tools/extract_ops.py
import yaml

HTTP_METHODS = {"get", "post", "put", "patch", "delete"}

def extract_operations(spec):
    for path, methods in spec["paths"].items():
        for method, op in methods.items():
            if method notin HTTP_METHODS:
                continue
            yield {
                "id": op.get("operationId") orf"{method}_{path}".replace("/", "_"),
                "method": method.upper(),
                "path": path,
                "summary": op.get("summary", ""),
                "parameters": op.get("parameters", []),
                "requestBody": op.get("requestBody", {}),
                "responses": op.get("responses", {}),
            }

if __name__ == "__main__":
    with open("openapi.yaml", encoding="utf-8") as f:
        spec = yaml.safe_load(f)
    ops = list(extract_operations(spec))
    with open("cases/raw_ops.yaml", "w", encoding="utf-8") as f:
        yaml.safe_dump(ops, f, allow_unicode=True, sort_keys=False)
    print(f"抽到 {len(ops)} 个 operation")

87个接口,抽出来87条operation。但这只是原材料,不是用例。

三、让AI干它擅长的:想场景

接口测试最烦的不是发请求,是想“还要测什么”。正常流谁都会写,缺参、类型错、边界值、权限、幂等——这些才费脑子。

我把每个operation的JSON发给模型,要求只输出JSON,不要解释:

你是一个接口测试专家。下面是一个OpenAPI operation的JSON。
请生成pytest参数化用例,输出JSON数组,每个元素包含:
{
"id": "唯一ID",
"name": "用例名",
"path_params": {},
"query_params": {},
"headers": {},
"body": {},
"expected_status": 200,
"expected_assertions": []
}
覆盖场景:正常流、缺参、类型错、边界值、权限异常。

实测效果:87个operation,AI生成了529条用例。平均每个接口6条——正好覆盖正常流、缺参、类型错、边界值、鉴权和幂等。

但AI生成的用例不能直接用。我让同事花了两小时做了一轮审核,主要检查三件事:

第一,断言写得太弱。 AI生成的断言往往是assert response.status_code == 200,只校验状态码。我要求改成assert data["code"] == 0 and data["data"]["orderId"] is not None。

第二,依赖关系没处理。 比如“取消订单”用例需要先有一个已支付的订单。AI不知道这个依赖,生成的用例直接调取消接口,必然404。

第三,业务规则缺失。 比如“已发货订单不能取消”——这条规则只存在于产品经理的脑子里,Swagger里没有。AI不知道,生成的用例就没覆盖。

AI负责把场景“想全”,人负责把断言“写对”。

四、用pytest动态执行

AI生成的JSON用例,不直接转成.py文件,而是用参数化的方式动态执行:

import pytest
import yaml
import requests

with open("cases/ai_cases.yaml") as f:
    ALL_CASES = yaml.safe_load(f)

@pytest.mark.parametrize("case", ALL_CASES)
def test_api(case, base_url, auth_token):
    url = base_url + case["path"]
    headers = {"Authorization": f"Bearer {auth_token}"}
    resp = requests.request(
        method=case["method"],
        url=url,
        params=case.get("query_params"),
        json=case.get("body"),
        headers=headers,
    )
    assert resp.status_code == case["expected_status"], (
        f"用例 {case['id']} 状态码不匹配"
    )
    for assertion in case["expected_assertions"]:
        # 简化示例,实际用jsonpath或schema校验
        assert assertion["key"] in resp.json()

为什么用参数化而不是生成静态文件?

因为Swagger在变,AI生成的用例也在变。参数化让用例和代码解耦——Swagger更新了,重新跑一遍AI生成流程,用例自动更新,不用改一行测试代码。

五、效果:3天到3小时

最终数据:

指标
手工Postman
AI+pytest
接口数
87
87
用例数
手工写500+
AI生成529条
全量回归
3天
3小时
MR冒烟
半天
20分钟
用例维护
手动改
Swagger更新后自动重生成
人工投入
3天/轮
2小时审核 + 全自动执行

最关键的变化不是“快了”,是“可以持续跑” 。以前手工点测,一个月跑一次就不错了。现在CI上每天跑,每次MR自动触发。

有团队在支付平台API测试中做了类似的尝试:Agent基于Swagger生成1200+用例,**用例生成时间从3天缩短到2小时,效率提升97%**。跨境支付汇率计算场景,资深工程师要琢磨2天的边界组合,AI用15分钟生成了27种参数组合的用例集。

六、踩过的坑

坑一:Swagger不干净,AI就编。

我一开始直接拿Swagger 2.0的文档喂模型,AI生成了大量不存在的字段。Swagger必须是OpenAPI 3.0,operationId唯一,必填和枚举写清楚。

坑二:只让AI“生成”,不让AI“想”。

如果你只说“生成测试用例”,AI会给你一堆assert 200的弱断言。你必须明确要求它覆盖正常流、缺参、类型错、边界值、权限、幂等六类场景。

坑三:依赖关系没处理。

“取消订单”依赖“已支付订单”,“退款”依赖“已支付订单”。AI不知道这些依赖,你需要给它一个依赖链的上下文,或者用Skills把依赖处理拆成独立步骤。

坑四:生成完不审核直接用。

AI生成的529条用例里,有大概60-80条需要人工修正。断言写弱了、业务规则漏了、依赖没配。审核2小时,比从零写500条用例省下来的时间不是一星半点,但审核这一步不能省。

最后

AI+Swagger的核心,不是“让AI写用例”,是“把Swagger变成可执行的测试契约”。

Swagger写清楚了接口的“是什么”——路径、参数、类型、响应。AI补上了“还要测什么”——缺参、边界、鉴权、幂等。pytest负责“怎么跑”——参数化、断言、报告。

你不需要再手写500条用例了。你只需要把Swagger弄干净,让AI补场景,让pytest去干重复劳动。

下次你面对一个几百个接口的项目,别打开Postman了。打开Swagger文件,跑一遍清洗脚本,把operation丢给AI,说一句:

“帮我生成pytest参数化用例,覆盖正常流、缺参、类型错、边界值、权限和幂等。”

3小时后,CI上会跑完500多条用例.

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。