告别硬编码断言!基于Skills的接口测试,智能体自动组合请求与校验(附代码)

接口测试做到第三轮迭代的时候,很多人会盯着满屏的 assert response.json()['code'] == 200 发呆。上游字段又改了,几十个用例里的断言要一个一个重写。改到一半测试同事离职了,接手的人看着硬编码的魔数直挠头。

更糟的是,现在很多团队开始用 Claude Code 或 Copilot 生成接口用例。生成是快了,但产出的东西依然是硬编码断言,该脆弱的还是脆弱,该爆炸的迟早会爆炸。

这不是工具的问题,是测试逻辑的封装粒度出了问题。今天聊一套从工程现场长出来的解法------用 Skills 把校验逻辑模块化,让智能体自动组合请求与校验

目录

  • 一、接口测试的"脚本地狱"正在吃掉你的时间

  • 二、从"写断言"到"教 AI 判断正确性"

  • 三、Skills 如何让智能体学会接口测试

  • 四、实战:从零搭一个自动组合请求与校验的智能体

  • 五、你缺的不是工具,是技能模块化思维

  • 六、最后一个问题


一、接口测试的"脚本地狱"正在吃掉你的时间

打开任何一个做了两年以上的接口测试仓库,你大概率会看到这样的代码:

复制代码
def test_login_success():
    resp = requests.post("/api/login", json={"user":"admin","pass":"123456"})
    assert resp.status_code == 200
    assert resp.json()["code"] == 0
    assert resp.json()["data"]["token"] != ""

这还只是"正常登录"一个用例。再加上密码错误、账号不存在、验证码过期、字段缺失......每个用例里都嵌着一堆完全重复结构的断言。字段名一改,全量重测。测试套件越写越像一本锁死版本的字典,业务一迭代,字典就变成废纸。

更让人焦虑的是,AI 代码助手来了。但它也学会了复制粘贴这种硬编码,只不过复制得更快、更多。硬编码断言的本质,是把测试人员的判断力锁死在脚本里,每一次业务变更都需要手工开锁。 效率提升的边际收益,全被维护成本吃掉了。


二、从"写断言"到"教 AI 判断正确性"

硬编码断言为什么脆弱?因为它在用"具体值"定义正确性。而正确的定义,本应来自接口契约和业务规则。

如果一个接口文档里写了"成功时返回状态码200,code字段为0,data.token为非空字符串",那么这个规则就不该被人肉翻译成三行 assert,而应该直接被机器消费。

这就是本质变化:接口测试的核心活动,正在从"编写用例脚本"转向"让智能体理解契约并自主校验"

这个转向里,校验逻辑必须从一次性脚本中解耦出来,变成可组合、可复用的独立单元。这些单元就是 Skills。


三、Skills 如何让智能体学会接口测试

一个 Skill 就是一个封装好的校验能力。比如:

Skill 名称 能力描述
HttpStatusCodeSkill 校验响应状态码是否符合预期
JsonPathExistsSkill 校验 JSON 路径是否存在且非空
JsonSchemaSkill 校验响应结构是否匹配 JSON Schema
ResponseTimeSkill 校验响应时间是否在阈值内
BusinessRuleSkill 校验自定义业务规则(如金额计算)

每个 Skill 都有标准接口:接收一段校验描述,输出一个可执行的校验函数。

而智能体的工作流,是把接口文档、测试场景和已有的 Skills 清单一起丢给大模型,让它自动规划"用哪些 Skill、按什么顺序、带什么参数"来完成这次校验。

流程如下:

核心在于:智能体不直接生成断言代码,而是生成一份校验计划。这个计划由 Skills 解释执行。 当接口字段变化时,只需要重新让智能体读取新的文档,重新生成校验计划,Skills 本身的代码一行不用改。


四、实战:从零搭一个自动组合请求与校验的智能体

我们直接看代码。下面是一个最小可运行的 Skills 执行框架,用 Python 实现。

第一步,定义 Skill 基类和两个基础 Skill:

复制代码
from abc import ABC, abstractmethod
import requests
import jsonpath_ng

class BaseSkill(ABC):
    @abstractmethod
    def execute(self, response, params: dict) -> tuple[bool, str]:
        """返回 (是否通过, 失败原因)"""

class HttpStatusCodeSkill(BaseSkill):
    def execute(self, response, params):
        expected = params.get("expected", 200)
        if response.status_code != expected:
            returnFalse, f"期望状态码 {expected}, 实际 {response.status_code}"
        returnTrue, ""

class JsonPathExistsSkill(BaseSkill):
    def execute(self, response, params):
        path = params["path"]
        matches = jsonpath_ng.parse(path).find(response.json())
        ifnot matches:
            returnFalse, f"路径 {path} 不存在或值为空"
        returnTrue, ""

第二步,构建 Skill 注册表:

复制代码
SKILL_REGISTRY = {
    "http_status_code": HttpStatusCodeSkill(),
    "json_path_exists": JsonPathExistsSkill(),
    # 更多 Skills 按需注册...
}

第三步,智能体规划与执行引擎:

这里用一段提示词让大模型(比如 Claude)根据接口文档输出校验计划。我们只把大模型返回的 JSON 计划接进来。

复制代码
import json

def run_test_from_plan(api_doc, plan_json):
    """
    plan_json 是智能体输出的校验计划,结构示例:
    {
      "request": {"method":"POST", "url":"/api/login", "body": {...}},
      "checks": [
        {"skill":"http_status_code", "params":{"expected":200}},
        {"skill":"json_path_exists", "params":{"path":"$.data.token"}}
      ]
    }
    """
    plan = json.loads(plan_json)

    # 发送请求
    req = plan["request"]
    if req["method"] == "POST":
        resp = requests.post(f"https://your-host{req['url']}", json=req.get("body", {}))
    else:
        resp = requests.get(f"https://your-host{req['url']}")

    # 逐个执行校验
    for check in plan["checks"]:
        skill_name = check["skill"]
        skill = SKILL_REGISTRY.get(skill_name)
        ifnot skill:
            print(f"[WARN] 未知 Skill: {skill_name}")
            continue
        passed, reason = skill.execute(resp, check.get("params", {}))
        ifnot passed:
            print(f"[FAIL] {skill_name}: {reason}")
        else:
            print(f"[PASS] {skill_name}")

# 模拟:智能体根据 API 文档生成的计划
mock_plan = '''
{
  "request": {
    "method": "POST",
    "url": "/api/login",
    "body": {"username":"admin","password":"123456"}
  },
  "checks": [
    {"skill":"http_status_code", "params":{"expected":200}},
    {"skill":"json_path_exists", "params":{"path":"$.data.token"}}
  ]
}
'''

run_test_from_plan(None, mock_plan)

当你需要增加新的校验维度时,只需新增一个 Skill 类,注册到字典里。智能体自然就能在下次规划时选用它。不用再一个用例一个用例地改断言。


五、你缺的不是工具,是技能模块化思维

回看上面的代码,会发现一个关键设计:执行器完全不关心接口是什么,Skills 不关心自己被谁调用。 这种解耦让测试套件的演化速度能跟上业务。

从工程落地角度,有三条可以直接拿走用的原则:

  1. 凡是重复出现三次的断言模式,必须抽取为 Skill。 状态码校验、字段存在性校验、类型校验,这些都是通用件。

  2. 让接口文档当唯一的真相源。 只要智能体能读懂 OpenAPI Spec,你就不需要再用人眼去对着文档写断言。

  3. 校验计划是可审计的。 智能体生成的 JSON 计划可以进版本管理,任何人随时能看清"这次接口测试到底查了哪些东西"。

这条路线走下去,测试人员的工作重心会从"写校验代码"转向"定义校验技能和审查校验计划"。前者的天花板是手速,后者的天花板是设计能力。


六、最后一个问题

你现在维护的那套接口测试,如果明天上游团队把接口字段全面重构,你需要改多少行断言?如果答案是"几乎全部",那说明你手里的不是测试资产,是负债。

当智能体已经能做到自动组合 Skills 完成校验,人该做的事,是设计出足够健壮的技能模块,让 AI 有兵可用。

你的断言复用率,现在有多少?

本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。

相关推荐
戴西软件14 小时前
AICrash智能行人保护:CAxWorks.VPG 如何让汽车安全仿真快人一步
人工智能·深度学习·汽车
木雷坞14 小时前
AI Gateway 接入大模型服务后首 token 慢排查:镜像、模型缓存和 GPU 节点
人工智能·缓存·gateway
2601_9578848414 小时前
企业短视频获客系统怎么选?AI矩阵运营为什么正在成为主流
人工智能
Ricky055314 小时前
YOLO26:实时目标检测的关键架构改进与性能基准测试(2025年10月美国研究)
人工智能·目标检测·目标跟踪
wenzhangli714 小时前
OoderAgent V3.5虚拟沙箱技术打破“一次性NLP“怪圈,让AI调试开发永不失效
人工智能·自然语言处理
wabs66614 小时前
本科毕业设计项目——基于RAG与大语言模型的408问答系统设计与实现【检索与生成功能的第二步文档检索是怎么实现的?】
人工智能·语言模型·自然语言处理
吃好睡好便好14 小时前
矩阵的求幂运算
人工智能·学习·线性代数·算法·matlab·矩阵
视觉&物联智能14 小时前
【杂谈】-筑牢AI安全防线:解锁运行时保护新密钥
人工智能·安全·chatgpt·aigc·agi·deepseek
巴巴博一14 小时前
【AI 赋能前端】告别手写样式!ui-ux-pro-max-skill 插件完整使用指南(附高阶 Prompt 模板)
前端·css·人工智能·ui