接口工具 + AI 文档生成

文档漂移是最贵的一类接口问题:写文档那天是对的,代码改完就错了,而没人主动去对。 直到有人照文档写代码被拒,第一反应还是「这人不会用」。

今天把这件事变成一个能重复跑的检查。

配套脚本在 examples/lab/day27/,五个文件都能直接跑,接口文档就在 /openapi.json,不需要装任何工具。

💸 一次手工排查的代价

那份文档是我自己写的,写完那天是对的。后来后端把金额从 double 改成 varchar,文档没跟着改。

这个错误在文档里躺了两个月。

暴露它的那天,排查路径是这样的:

  1. 照文档发请求 → 400
  2. 怀疑自己参数写错 → 改了三种写法,还是 400
  3. 怀疑接口有 bug → 翻服务端日志,没报错
  4. 最后才想起来「文档是旧的」

第 4 步之前的所有时间,都是因为没人把「文档说的」和「实际做的」放一起对过。

🔍 对的方式:照文档造一个值发过去

python 复制代码
def 按文档试一次(base, doc, path, method, field):
    schema = doc["paths"][path][method]["requestBody"]["content"]["application/json"]["schema"]
    doc_type = schema["properties"][field]["type"]

    样例 = {
        "string": lambda: "199.80",
        "number": lambda: 199.8,
        "integer": lambda: 200,
        "boolean": lambda: True,
    }
    value = 样例[doc_type]()
    response = requests.post(f"{base}{path}", json={field: value}, timeout=5)
    return doc_type, value, response.status_code


doc_type, value, status = 按文档试一次(base, doc, "/orders", "post", "amount")
if status >= 400:
    print(f"文档和实现对不上:文档说 {doc_type},接口不收")

这个检查的巧妙之处在于归因。 OpenAPI 规范见 官方文档,常见状态码语义见 MDN 参考,requests 用法见 官方快速上手。

请求是照着文档造出来的,所以它被拒这件事,错的只能是文档------不可能是你的参数写错,因为你是严格照着文档写的。

实测结果:文档说 number,发过去 400 amount_must_be_string;发字符串 201。

🔁 为什么值得天天跑

文档漂移的阴险之处在于它平时不出事。

  • 写文档那天是对的
  • 代码一改,文档就错了
  • 没有任何人会主动去对,除非有人刚好踩到

而踩到的人会付出上面那 4 步的时间。更糟的是,他会把结论归到「接口难用」或者「自己不会」,不会想到文档。

所以这个检查的正确位置是 CI:

text 复制代码
python -m pytest examples/lab/day27 -q

人不会去看 wiki,但 CI 会拦人。

📋 从文档生成用例:快的部分和慢的部分

生成本身很快,三十行代码:

python 复制代码
def 从文档造用例(doc):
    用例 = []
    for path, methods in doc["paths"].items():
        for method, info in methods.items():
            method = method.upper()
            body = info.get("requestBody")
            if body:
                schema = body["content"]["application/json"]["schema"]
                必填 = schema.get("required", [])
                字段 = schema.get("properties", {})
            else:
                必填, 字段 = [], {}

            用例.append({
                "编号": f"TC_{method}_{path.replace('/', '_').replace('{','').replace('}','')}",
                "方法": method,
                "路径": path,
                "请求": {k: 按类型造值(v["type"]) for k, v in 字段.items() if k in 必填},
                "预期状态码": 201 if (method == "POST" and "{" not in path) else 200,
                "前置": "(文档没写)",
                "预期结果": "(文档没写)",
            })
    return 用例

它省掉的是「抄一遍参数」。 三个接口三十行代码 vs 手写三遍路径和字段,这个省下的时间是实打实的。

但它有个前提问题:它只能抄文档里有的东西。

跑一遍你会发现,生成的第一条直接挂了:

text 复制代码
TC_POST__orders              预期 201 实际 400  不符
TC_GET__orders_order_id      预期 200 实际 200  符合
TC_POST__orders_order_id_cancel  预期 200 实际 200  符合

因为它照文档造了 {"amount": 199.8},而文档是错的。

修法不是改用例,是改文档。

生成的骨架覆盖不到什么

  • 金额传错类型会怎样
  • 订单不存在会怎样
  • 已支付的订单取消会怎样
  • 重复取消会怎样
  • 谁有权限取消别人的订单

这五类生成一条都生成不出来。 文档只说了「正常长什么样」,没说「不正常的时候该怎么反应」。

生成能省掉抄参数的活,省不掉想清楚不正常时会怎样。 后者才是接口测试真正值钱的部分。

🤖 AI 起草反例:能省,但省不了判断

AI 给五条反例,其中一条特别值得说:

AI 写的用例 AI 写的预期 实际
别人能不能取消我的订单 返回 403 权限不足 200

这个服务根本不校验身份。 照 AI 的预期写断言,这条会永远红------而你会以为是接口有 bug。

问题不在于 AI 猜错了状态码,在于**「403 权限不足」这个预期本身就没有来源**。「别人能不能取消我的订单」是条业务规则,可这条规则没人写过。AI 猜了一个最常见的答案,你照抄,就等于把一个自己都不知道的规则写进了测试。

另外三条的毛病轻一些但同样真实:

  • 「取消订单」------没说要再查一次(Day26 那个四层断言)
  • 「重复取消订单」------没说这次其实什么都没改 (changed=False)
  • 「金额传成数字」------猜对了 400,但事先不知道是 400 还是 422,得跑一次才知道

📌 落到工程上的三条

一、漂移检查挂 CI,不挂 wiki。 一个 pytest 用例加一条命令的事。

二、从文档生成骨架可以自动化,但它只是起点。 生成的用例跑一遍就发现了文档漂移------这本身就值了。

三、AI 起草之后必须实跑确认。 特别是不靠文档、靠推理得出的状态码。

🗂️ 一个能把生成用例真正用起来的目录结构

text 复制代码
lab/
├── stub_api.py          教学服务(也是后面几天的公共依赖)
├── day27/
│   ├── conftest.py      fixture:本地服务、接口文档
│   ├── 01_read_docs.py  读文档、列清单
│   ├── 02_doc_drift.py  漂移检查
│   ├── 03_generate_cases.py  从文档生成骨架
│   ├── 04_ai_draft.py   AI 起草 + 逐条核对
│   └── 05_answer.py     练习答案

服务放最外层,因为后面六天都要用它。 Day28 要用它测断言,Day29 要用它做 Mock,Day32 要拿它跑配置化用例。

每天一个独立目录。 你 cd 进去跑,不用记得先 cd 到哪。

fixture 单独一份。 pytest 会自动加载 conftest.py,里面放的 fixture 不用 import 就能用。

为什么这么摆? 因为接口测试最容易烂在「改一个东西,十几个文件都要翻」。把服务、fixture、测试分开之后,改断言不动服务,改服务不动断言。

🧮 一个跨天的数字

成功支付总额一直是 359.60,被七种不同的实现算出来过:SQL 的 SUM、纯函数的 for 循环、类的组合、标准库的 Counter、requests 加 Pydantic、pytest 的断言。

每次换技术栈都重新算一遍,数字一样。

为什么较这个劲? 因为「过滤条件被顺手改掉」是这类代码最常见的错误,而它不会让任何测试变红------测试和新代码是一起改的。只有一个来自别处、来自另一种技术实现的数字,才能发现。

📝 三个练习

  1. 列出接口清单 ------ 3 个,方法和说明都要对。
  2. 把漂移检查写成 pytest ------ 文档说是 number,实跑被拒 400,错误码 amount_must_be_string。
  3. 给 AI 起草的用例补观察点 ------ changed 分别 True 和 False,最终状态 CANCELLED。

第 2 题有个容易搞混的地方:它测的不是「接口应该拒绝数字」,是「文档和实际对不上」。 文档修好之后这个测试就该红了(漂移没了)。真正要挂 CI 的是反过来的一版。

🔭 最后

文档漂移是接口测试里最贵的一类问题,因为它平时完全隐形。

从文档生成用例是真的快,但你要清楚它只干了「抄参数」这一件事。真正花时间的是后半截------哪些不正常的情况值得测、测到了算过还是算不过。

这部分文档给不了,AI 也给不了。

下一步是 Day28《接口自动化 + AI 智能断言》,我们把断言写死的字段变成能配的东西,并且用一份故意坏的响应,证明这些断言真的能抓住错。

相关推荐
会开车的鸟哥1 小时前
编写测试序列与测试评估完整示例
程序员
codigger5 小时前
别再手动催 AI 干活了:一文读懂 Loop Engineering(循环工程)
ai·程序员·编程语言·#人工智能
挖掘狂人5 小时前
别再手动催 AI 干活了:一文读懂 Loop Engineering(循环工程)
人工智能·程序员·ai编程
千里马学框架5 小时前
Service服务绑定对进程adj影响及常见绑定错误
android·智能手机·性能优化·程序员·framework·性能·安卓失业
kyriewen19 小时前
我让 4 个 AI 互相 review 代码,最温柔的那个下手最狠
前端·程序员·ai编程
程序员cxuan21 小时前
掀桌子了!Kimi K3.1 Pro 这效果也太离谱了。
人工智能·后端·程序员
不脱发的程序猿1 天前
红利ETF量化策略
人工智能·python·ai·程序员·量化交易·etf·策略回测
陈随易1 天前
终于 Token 自由了,AI 开支下降 10 倍
前端·后端·程序员
codigger1 天前
别再靠"最终版-改"活下去了:一篇讲透 Git 与 GitHub
git·程序员·github·编程·控制版本