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

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多条用例。

相关推荐
sell-cloud9 小时前
Prompt Engineering要凉了?Fable 5.5能“猜“意图,但银行正在封杀AI Agent——企业AI的真正护城河是什么
人工智能·prompt
Navicat中国11 小时前
Navicat 18 内置 AI 助手让数据库开发从繁琐操作迈向智能协作
大数据·人工智能·数据库开发
4SAPI11 小时前
多模型请求路由怎么设计?成本、速度和能力如何平衡
人工智能·python·gateway·php
魔乐社区11 小时前
翼芯・智算测试与适配优化专区,让国产算力“选得准、跑得通、用得好“
人工智能·开源·大模型
XCDoris13 小时前
郴州logo设计机构
大数据·人工智能·python
Goboy13 小时前
一个人带三个Agent,我用全新TRAE从0到1搭了个资讯周刊站
人工智能·trae
俊哥V13 小时前
每日 AI 研究简报 · 2026-10-19
人工智能·ai
AI_AGENT_DEV_AI13 小时前
AI英语教培智能体的开发
人工智能
物联网软硬件开发-轨物科技14 小时前
【技术白皮书】光伏清检一体化机器人系统解决方案技术白皮书
大数据·运维·网络·人工智能·机器人
海宇数据14 小时前
零信任架构实战:基于海宇网上踪迹欺诈行为识别构建自动化信贷资信评估网关
运维·人工智能·架构·自动化