自动化工具 【开源】全新一代 Aomaker 发布!——重塑接口自动化测试的工程范式

古一 · 2025年04月29日 · 最后由 难以怀瑾 回复于 2025年04月29日 · 64 次阅读

一、前言

一转眼,距离上次在社区发 aomaker V2 已经过去一年多了:
https://testerhome.com/topics/37899

诚惶诚恐,今天我带着 V3 又来了😁 ..

有做 aomaker V3 的想法是从发现attrs 开始的...

可惜 24 年一整年属实太忙了,实在没时间动手,这个想法就一直搁置到今年年初,趁着过年 + 陪产假,花了一个月完成了 aomaker V3 的核心功能开发,然后发了个 beta 版到群里给群友测试使用,这一 beta,beta 了 16 个版本,业余时间修修补补 + 测试又搞了两月...

描述文本

今天,终于赶在伟大的工人阶级节日前,可以发布了...

下面正文开始👇🏻


二、介绍

现状

过去这些年,接口自动化领域几乎大部分框架都把精力聚焦在测试用例层

  • 关键字驱动 / 模板引擎
  • 数据驱动 / 参数化
  • 断言 DSL / 报告可视化

这些技术已经相当成熟。以 Python 生态为例,Pytest / unittest 早就提供了完备的用例组织、发现、并发和报告能力。

对于企业级的接口自动化测试场景,真正的挑战是否仅停留在用例层?

困境

非也,当我们深入企业级接口自动化场景时会发现,真正的痛点并非在用例层。

真正未被有效解决的,是接口本身的 “工程化定义”,是高频迭代中接口维护带来的挑战

  • 接口参数随业务快速变化
  • 版本迭代导致接口路径频繁修改
  • 接口定义与文档脱节:人工维护代码与 OpenAPI/Swagger 文档一致性成本极高
  • 多环境切换带来的配置管理复杂度
  • 团队协作中的接口定义一致性难题

传统方案在应对这些挑战时,往往陷入"接口定义散落测试用例"、"参数维护成本指数级增长"的困境。

痛点

如何保证接口的高可维护性?我们先看下传统有哪些方案。

方案一: 原始请求直连

def test_get_containers():
    response = requests.get(url="http://example.com/api/usr-xxx/containers?limit=10")
    assert response.status_code == 200
  • 优点:实现简单、直观,适合小型项目或快速验证。
  • 缺点:复用性极差,接口 URL 和参数直接硬编码在用例中。当接口数量增加或需求变更时,修改工作量巨大,维护成本随规模膨胀呈指数级上升,难以工程化,停留在 “脚本” 级别。

方案二: 基础接口抽象

class BaseApi:
    host = "http://example.com"
    headers = {"Content-Type": "application/json"}

    def send_http(self, data: dict):
        try:
            response = requests.request(**data)
            return response
        except Exception as e:
            raise e

class ContainersApi(BaseApi):
    def get_containers(self, namespace, limit=10):
        url = f"{self.host}/api/{namespace}/containers?limit={limit}"
        data = {
            'url': url,
            'method': 'get',
            'headers': self.headers,
        }
        return self.send_http(data)

def test_get_containers():
    api = ContainersApi()
    response = api.get_containers(namespace="usr-xxx", limit=10)
    assert response.status_code == 200
  • 优点:通过类封装实现接口层与用例层的解耦,提升了复用性。
  • 缺点:接口参数和 URL 仍硬编码在方法中,缺乏结构化管理。当参数增多或接口逻辑复杂时,维护难度依然较高,扩展性受限。

方案三: 接口抽象 + 接口参数建模

from dataclasses import dataclass

@dataclass
class GetContainersParams:
    namespace: str
    limit: int = 10

class ContainersApi(BaseApi):
    def get_containers(self, params: GetContainersParams):
        url = f"{self.host}/api/{params.namespace}/containers?limit={params.limit}"
        data = {
            'url': url,
            'method': 'get',
            'headers': self.headers,
        }
        return self.send_http(data)

def test_get_containers():
    params = GetContainersParams(namespace="usr-xxx", limit=10)
    api = ContainersApi()
    response = api.get_containers(params)
    assert response.status_code == 200
  • 优点:通过数据类(如 dataclass)将参数与接口定义解耦,参数初步结构化,使之管理更清晰。
  • 缺点:URL 和参数拼接仍需手动处理,缺乏强约束和结构化描述。接口层被抽象为接口类、定义层和数据模型层三层,调用复杂,且 IDE 支持有限,开发者无法直观获取参数提示。

以上三种方案体现了APIObject思想的逐步演进,但仍未达到理想状态,传统方案始终存在"定义碎片化"与"维护复杂度"的矛盾。

接口维护的痛点——硬编码、缺乏约束、调用复杂性——并未彻底解决。

那,有没有更优的方案?

解决方案

基于上述挑战,aomaker V3应运而生。

aomaker V3 的全新解法:用模型描述接口,让文档驱动代码。

我认为,解决接口自动化维护难题的关键,在于接口本身的工程化定义

aomaker V3 摒弃了将接口信息零散分布在代码或简单封装中的传统做法,引入了声明式的接口对象化建模

1.核心理念和实现

接口建模

aomaker V3 选择使用attrs库作为建模工具,利用其强大特性,将接口的每一个要素(URL、方法、路径参数、查询参数、请求体、响应体等)结构化地定义在一个 Python 类中。

通过声明式定义让接口结构一目了然,代码即文档,文档即代码,告别硬编码和手动拼接的混乱。

接口定义示例:

from attrs import define, field 

from aomaker.core.router import router
from aomaker.core.api_object import BaseAPIObject


@define(kw_only=True)  
@router.get("/api/{namespace}/containers")  
class GetContainersAPI(BaseAPIObject[ContainersResponse]):  
    """获取容器列表"""  

    @define  
    class PathParams:  
        namespace: str = field()  

    @define  
    class QueryParams:  
        offset: Optional[int] = field(default=0)  
        limit: Optional[int] = field(default=10)  
        name: Optional[str] = field(  
            default=None, metadata={"description": "容器名称, 模糊搜索"}  
        )  
        reverse: Optional[bool] = field(  
            default=True, metadata={"description": "按时间倒序排列"}  
        )  
        order_by: Optional[str] = field(  
            default="created_at", metadata={"description": "排序字段"}  
        )  

    path_params: PathParams  
    query_params: QueryParams = field(factory=QueryParams)  
    response: Optional[ContainersResponse] = field(  
        default=ContainersResponse  
    )

用例层调用示例:

from apis.containers.api import GetContainersAPI


def test_notebooks_get():  
    path_params = GetContainersAPI.PathParams(namespace="usr-xxx")  
    query_param = GetContainersAPI.QueryParams(limit=100)  
    res = GetContainersAPI(path_params=path_params, query_params=query_param).send()  
    assert res.response_model.ret_code == 0

看到 GetContainersAPI.PathParams(namespace=...)res.response_model.ret_code 了吗?

这就是 aomaker 带来的改变!

接口的请求参数和响应结构都被定义为清晰的 Python 对象。

在你的 IDE 中,无论是填充 path_params 还是访问 response_model,全程都有精准的智能提示和类型检查。再也不用猜测参数名,也不用面对 res['data'][...] 这样的 “黑盒”,开发体验和代码健壮性直线提升!

为什么选择 attrs?

相比dataclass的轻量但功能有限,以及pydantic的强大但过于繁重,attrs 恰好平衡了两者优点:

  • 简单直接,减少样板代码;
  • 支持类型注解和内置验证器,同时允许灵活关闭强校验,适应接口测试中验证异常参数的需求;
  • 性能优化后接近手写代码,运行高效。

更多attrs 特性可查看官方文档

觉得这套结构化定义略显复杂?没关系,这些其实都可以一键自动生成!👇🏻

文档驱动测试开发

aomaker V3 的一大亮点是与OpenAPI 3.xSwagger 2.0的深度集成,支持从 API 文档中一键生成接口定义模型

只需一行命令即可搞定。

这一功能极大地简化了接口定义的过程,提升了开发效率和准确性,尤其适用于大型项目或 API 频繁迭代的场景。

  • 自动化生成:测试人员无需手动编写复杂的接口模型。只需导入项目的 OpenAPI 3.x 或 Swagger 2.0 文档,aomaker V3 即可自动解析并生成相应的 attrs 模型,包含路径参数、查询参数、请求体和响应体的定义。

  • 确保一致性:自动生成的模型与 API 文档严格同步,确保接口定义的准确性,减少人为错误的可能性。

  • 提升效率:测试人员可以快速适应接口变更,专注于业务逻辑和测试用例的编写,而无需担心接口定义的细节。

2.这意味着什么?

通过接口建模与文档驱动,aomaker 不仅仅是提供了一种新的工程范式,更是解决了一些传统接口自动化测试的老痛点:

  • 告别混沌,拥抱工程化: 接口定义不再是散落各处的神秘代码或脆弱约定。结构化的模型和与文档的强绑定,将接口管理提升到工程化水平,从根本上解决了定义混乱和维护困难的问题。
  • 维护成本的指数级下降: 想象一下修改一个接口需要同步多少测试脚本?甚至很多时候,你甚至都不知道接口发生了什么变更!在 aomaker 中,修改通常只涉及对应的模型类。无论接口发生什么变更,只需一键同步接口文档,让你从容应对快速迭代。
  • 开发体验与效率的双重提升: 精准的 IDE 提示、简洁的调用方式、一键生成的便利性... 这些都意味着更少的错误、更快的开发速度和更愉悦的编码体验。测试人员可以真正聚焦于业务逻辑验证,而不是接口定义的细节。
  • 灵活性与测试深度兼顾: 基于 attrs 的模型不仅结构清晰,还提供了灵活的参数校验机制,方便你测试各种正常及异常边界场景。同时,模块化的设计也易于团队协作和功能的扩展。

3.与传统方案的对比

特性 方案一 方案二 方案三 aomaker V3
接口定义方式 硬编码 部分抽象 参数建模 声明式建模 + 自动化生成
可维护性 😞 差 😐 一般 🙂 中等 😄 高
IDE 支持 🚫 无 🔧 弱 🔨 一般 🛠️ 强
参数管理 📋 无结构 🔒 硬编码 📐 结构化但弱 🏗️ 强结构化
扩展性 📉 差 📊 一般 📈 中等 🚀 高
API 文档集成 ❌ 无 ❌ 无 ❌ 无 ✅ 支持 OpenAPI/Swagger

4.总结

aomaker 通过重塑接口定义与管理的方式,旨在将接口自动化从繁琐的 “脚本维护” 提升为高效的 “工程实践”。

当接口的维护难题被解决,上层的测试用例编排就是手拿把掐的事。

因为底层的每一个接口定义都被制作成了标准化的 “积木”(API Object),上层无非就是根据业务场景进行 “积木拼装”(用例组织)罢了。所以,这就是为什么这个框架叫 aomaker 的原因:API Object Maker

用框架解决重复繁琐劳动,让测试工程师专注于核心逻辑验证。

当然,aomaker 不仅仅只有接口建模和自动生成,还有一系列配套工具链帮助你打造自动化测试工程!👇🏻


三、特性速览

aomaker 并没有重复造轮子,而是选择pytest 作为底层单元测试框架,积极拥抱 pytest 生态,支持并兼容所有pytest 插件。

如上所述,aomaker 并没有在用例层做太多革新,所以,你以前是怎么组织编排用例的,现在也是一样。

aomaker 提供的,如下:

  • 🚀 声明式接口建模: 使用 Python attrs 库定义接口,代码即文档,清晰直观,告别繁琐的硬编码和手动拼接。

  • 📄 OpenAPI/Swagger 无缝集成: 支持从 OpenAPI 3.x 和 Swagger 2.0 文档一键生成类型安全的接口模型代码,确保测试代码与 API 定义的强一致性。

  • ✅ 灵活的参数校验attrs 提供内置校验器,同时允许灵活关闭强校验,完美适配接口测试中对正常及异常参数的验证需求。

  • 🔄 自定义请求转换器: 内置钩子允许轻松定制请求转换逻辑,适配前端请求包装、微服务网关等各种复杂场景。

  • 🔬 JSON Schema 自动校验: 自动提取接口定义的响应模型生成 JSON Schema,并在每次请求后自动校验响应结构的完整性和类型,有效防止接口契约破坏。

  • 💾 强大的存储管理: 基于轻量级 SQLite 数据库,提供线程安全的全局配置管理 (config)、会话级缓存 (cache)、Schema 存储 (schema) 和接口元数据统计 (statistics)。

  • 🔑 灵活的鉴权管理: 支持多种认证方式,提供简洁的 API 实现登录认证逻辑,并支持请求头动态覆盖与作用域管理。

  • ⚡ 高效并行测试: 支持多线程多进程两种并行模式,提供按标记、文件、套件等多种任务分配策略,加速大规模测试执行。

  • 🔌 可扩展的中间件系统: 允许注册自定义中间件,在请求发送前和响应接收后执行自定义逻辑(如日志记录、Mock、重试、性能统计等)。

  • 🌊 HTTP 流式响应支持: 内置对流式响应的处理能力,适用于大数据传输、实时数据获取等场景。

  • 🛠️ 配套工具生态:

    • Mock Server: 内置功能丰富的 Mock 服务,提供大量示例接口,方便快速上手和调试。
    • Dashboard: 提供 Web UI 实时监控测试执行进度、日志和环境配置。
    • CLI 工具: 提供脚手架创建、用例运行、模型生成、服务启动、静态统计等便捷命令。
    • 测试报告 : 提供优化版 allure 测试报告和 aomaker 专属测试报告。
    • 测试平台 : 提供丰富内部框架接口,测试平台可以快速方便接入。

四、1 分钟快速上手

aomaker 提供了 mock server 和大量示例接口,帮助使用者理解 aomaker 的工程范式并快速上手。

0.安装

先创建虚拟环境,这里推荐uv ,然后进入虚拟环境,执行:

pip install aomaker

1.创建脚手架

# 创建脚手架
aomaker create xxx
# 进入脚手架项目
cd xxx

描述文本

2.开启 mock server

为了调用预置的 mock 接口,先开启 mock 服务:

aomaker mock start --web

可以查看接口文档

3.根据接口文档自动生成接口定义

脚手架已经预置了 mock 接口的定义,也可以体验如何自动生成。

执行自动生成后,会在项目根目录下的 apis/mock2 目录下生成模型定义代码。

aomaker gen models -s http://127.0.0.1:9999/api/aomaker-openapi.json -o apis/mock2

-s 指定接口文档位置,可以是 url,也可以是本地文件(JSON/YAML),-o 指定最终生成代码的目录。

更多参数和用法可以通过 aomaker gen models --help 查看。

4.运行测试用例

执行:

arun -e mock -m mock_api

arun 是 aomaker 运行测试用例的主命令,-e 为环境切换参数,-m 为指定运行哪些标记的测试用例(用法完全同 pytest)。

更多参数和使用方法可以通过 arun --help 查看。

5.查看测试报告

测试报告位置:项目根目录下 reports/aomaker-report.html

6.查看 aomaker live console(可选)

可以在开始运行用例前,打开该页面,可以实时查看各个子进程的用例执行进度和日志。

打开方式:

aomaker service start --web

五、核心特性剖面

1. 模型定义:接口=类 + 装饰器

一句话:用 @router.* + attrs 声明接口,调用时就能让 IDE 自动补全路径 / 参数 / 响应类型。

三步即可:

1.导入

from attrs import define, field
from aomaker.core.router import router
from aomaker.core.api_object import BaseAPIObject

2.声明

@define(kw_only=True)
@router.get("/api/users/{user_id}") # 指定路由和请求方法
class GetUserAPI(BaseAPIObject[UserResponse]): # ▶️ IDE 可提示 UserResponse 字段

    @define
    class PathParams: user_id: int = field()
        path_params: PathParams

    response: UserResponse = UserResponse

定义接口类名(推荐以API结尾),继承接口基类BaseAPIObject,如果需要在调用接口响应时有 IDE 自动补全和提示,需要指定响应模型泛型类。

一个接口类下主要有 4 个核心参数:

  • path_params: 路径参数,替换路由中{} 的内容
  • query_params: 查询参数
  • request_body: 请求体
  • response: 响应

推荐按以下方式进行管理:

apis/
├── xxx/            # 接口类型
│   ├── apis.py           # 该类型下所有接口对象定义
│   └── models.py         # apis.py中所有嵌套模型定义
└── ...                   # 其他接口类型

Tips:

虽然支持手动编写接口定义,但还是强烈建议通过接口文档进行自动生成!

更多示例和用法介绍(查询列表、POST 带 Body、嵌套模型…)👉 可查看官方文档「基础特性 - 模型定义」章节。

2.一键生成接口模型定义

一句话:一行命令,把 Swagger / OpenAPI 文档变成可运行的 API 模型,省掉 90 % 手工敲代码。

⚡ 只需 3 步

# 1. 拉起本地或远程接口文档
SPEC=http://127.0.0.1:9999/api/openapi.json

# 2. 一键生成 attrs 模型
aomaker gen models -s $SPEC -o apis/demo

# 3. 编写测试用例并执行
arun -m demo_api

生成结果:

apis/demo/
├── orders/      ← tag 自动分包
│   ├── apis.py      # API 对象
│   └── models.py    # 请求 / 响应模型
└── users/ …

🧩 命名策略

生成的接口模型类类名可以根据接口文档情况,自行定义。

需求 用何策略
文档里有 operation_id operation_id(默认)
想用接口摘要 summary
希望 “Tag + Path + Method” tags
还不满足? 自定义 Python 函数
# conf/naming.py
from aomaker.maker.models import Operation

def custom_naming(path:str, method:str, op:Operation) -> str:
    # /api/v1/user/login  →  UserLoginAPI
    last_two = [p for p in path.split('/') if p][-2:]
    camel = ''.join(s.capitalize() for s in last_two)
    return f"{camel}API"

aomaker gen models -s $SPEC -o apis/demo --cs conf.naming.custom_naming

🔧 持久化配置

把常用参数写进 conf/aomaker.yaml

openapi:
  spec: api-doc.json
  output: apis/demo
  class_name_strategy: operation_id      # 或 tags / summary
  # custom_strategy: conf.naming.custom_naming

以后只需:

aomaker gen models        # 配置即生效

想了解完整 CLI 选项?👉 查看官方文档「基础特性 - 接口文档一键生成」章节。

3.存储管理

一句话:配置、缓存、契约、统计——统统放进同一个 aomaker.db,零运维、线程安全、低成本。

设计初衷

为解决多任务环境下测试变量管理难题,aomaker 采用 SQLite 数据库作为核心存储方案。SQLite 作为轻量级嵌入式数据库,具备零配置、无服务端、单文件存储等特点,完美契合测试框架对轻量化与便捷性的要求。

四张核心表

项目初始化时自动创建aomaker.db数据库文件,内置四张功能明确的表结构:

表名 生命周期 存储内容 典型应用场景
config 持久化存储 全局配置参数 环境 host/账号信息等
cache 会话级存储 临时变量/依赖数据 接口依赖参数传递,临时变量
schema 持久化存储 接口响应模型 JSON Schema 响应结构验证
statistics 持久化存储 接口元数据统计 测试平台数据可视化

典型用法速览

全局配置管理

存放全局环境配置、账号登信息。

# 配置文件示例(conf/config.yaml)
env: test
test:
  host: http://test.aomaker.com
  account: 
    user: aomaker002
    pwd: 123456
# 代码调用示例
from aomaker.storage import config

def test_env_config():
    current_env = config.get("env")  # 获取当前环境
    test_host = config.get("host")  # 获取对应环境host

临时变量缓存

管理测试进程中的一些临时变量,如上游依赖等等。

from aomaker.storage import cache

def setup():
    cache.set("auth_token", "Bearer xxxxx")  # 设置鉴权令牌

def test_api_call():
    headers = {"Authorization": cache.get("auth_token")}  # 获取缓存令牌

JsonSchema 契约校验

当接口请求发送拿到响应后,会自动根据schema表中存储的该接口响应模型的 JSONSchema 信息做校验。

例如某个接口的响应模型为UserResponse


@define(kw_only=True)  
class GenericResponse:  
    ret_code: int = field(default=0)  
    message: str = field(default="success")

@define(kw_only=True)  
class User:  
    id: int = field()  
    username: str = field()  
    email: str = field()  
    created_at: datetime = field()  
    is_active: bool = field(default=True)

@define(kw_only=True)  
class UserResponse(GenericResponse):  
    data: Optional[User] = field(default=None)

UserResponse 模型对应的 JsonSchema 为:

{  
  "title": "UserResponse",  
  "type": "object",  
  "properties": {  
    "ret_code": {  
      "type": "integer"  
    },  
    "message": {  
      "type": "string"  
    },  
    "data": {  
      "anyOf": [  
        {  
          "title": "User",  
          "type": "object",  
          "properties": {  
            "id": {  
              "type": "integer"  
            },  
            "username": {  
              "type": "string"  
            },  
            "email": {  
              "type": "string"  
            },  
            "created_at": {  
              "type": "string",  
              "format": "date-time"  
            },  
            "is_active": {  
              "type": "boolean"  
            }  
          },  
          "required": [  
            "id",  
            "username",  
            "email",  
            "created_at"  
          ]  
        },  
        {  
          "type": "null"  
        }  
      ]  
    }  
  },  
  "required": []  
}

最终每个响应模型对应的 JsonSchema 会自动生成并自动存到schema 表中:

Schema & Statistics:首次调用即生成 JSON Schema 并记录元数据,可直接对接测试平台做覆盖率热图、性能趋势等报表。

详细字段与索引设计👉 见官方文档「基础特性 - 存储管理」章节。

4.并行运行:多线程/进程双模式,火力全开

一句话:一条 arun --mt/--mp 命令,线程或进程随心切,标签 / 文件 / 套件三档调度,Allure 报告照样稳。

🚀 能力速览

维度 说明
并发模式 多线程 --mt(轻量)
多进程 --mp(CPU 密集型场景优选)
任务分配 - mark:标签级
- file:测试模块级
- suite:目录级
报告兼容 避免 pytest-parallel 常见的多线程写文件冲突
一键策略 dist_strategy.yaml 批量声明 worker / 标签
动态核心数 进程模式自动取可用 CPU;-p 8 手动限核

⚡ 常用 命令

# 线程并发,按标记分配
arun --mt --dist-mark "smoke regress"

# 进程并发,按测试文件分配
arun --mp --dist-file testcases/api

运行完自动聚合报告并清理环境。

🗂️ 大规模用例?用 worker 分发策略

conf/dist_strategy.yaml

target: ['iaas', 'hpc']
marks:
  iaas:
    - iaas_image
    - iaas_volume
  hpc:
    - hpc_sw
    - hpc_fs

随后:

arun --mt        # 或 arun --mp

框架按策略自动拆分 4 个 worker 并发;改场景只需改 target,CLI 不变。

👉 更多自定义参数(核心数 -p, 忽略失败重跑等)请见文档「高级特性 - 并行运行测试用例」。

5.中间件:在 “请求 → 响应” 链路里插上任意插件

一句话:少量代码 + 1 个配置,就能为每个接口挂上日志、Mock、重试、性能统计等自定义逻辑。

🧩 机制一览

  • 可插拔:任何 callable(request, next) -> response 都能成为中间件
  • 可配置middlewares/middleware.yaml 切开/调序,无改代码
  • 可观测:内置日志中间件,支持自定义性能阈值报警

⚡ 30 秒上手

# middlewares/retry.py
from aomaker.core.middlewares.registry import middleware,registry

@middleware(name="retry", priority=800, enabled=True,
            options={"max_retries": 3, "codes": [500, 502, 503]})
def retry_mw(request, call_next):
    for _ in range(registry.middleware_configs["retry"].options["max_retries"]):
        resp = call_next(request)
        if resp.status_code not in registry.middleware_configs["retry"].options["codes"]:
            return resp   # 成功即返回
    return resp            # 重试后仍失败

# middlewares/middleware.yaml
logging_middleware: # 内置
  enabled: true
  priority: 900

retry:         # 👈 名称与装饰器保持一致
  enabled: true
  priority: 800
  options:
    max_retries: 3
    codes: [500, 502, 503]

启动 arun,框架自动扫描 middlewares/,按 priority → options 执行。

常见插件思路

用途 关键点 典型做法
结构化日志 全链路 request/response 开箱即用 logging_middleware
Mock / 桩服务 URL 规则匹配,返回 CachedResponse 示例:拦截 /products → 自定义 JSON
性能统计 记录 time.time() 差值,慢阈值报警 options: {slow_threshold: 1.0}
断网重试 捕获 RequestException 循环调用 next 见上方 Retry 示例

更多内置中间件与高级写法 👉 官方文档「高级特性 - 注册自定义请求中间件」。

6. 自定义接口转换器: 把 “接口模型” 翻译成你想要的任何请求格式

一句话:当真实网络流量≠接口文档时,只需继承 RequestConverter 重写 1 个钩子,就能让 aomaker 发送完全贴合业务网关 / BFF / 签名规则的请求。

🧩 典型场景

场景 文档里的 URL / Body 线上流量 痛点
微服务网关 /api/containers/{ns}/list POST /global_api/ + params={"action": ".../list"} 用例想100% 复现用户轨迹
加密签名 普通 JSON 统一 POST /proxy + AES 包体 需要在请求前注入签名字段
公共参数 文档未列出 实际必须带 owner / service 手写硬编码 & 复制粘贴难维护

⚡ 自定义只要 3 步

# 1. 继承 RequestConverter
@define
class GatewayConverter(RequestConverter):
    def post_prepare(self, req: PreparedRequest) -> PreparedRequest:
        body = {"params": json.dumps(req.request_body or {}), "method": req.method}
        return PreparedRequest(
            method="POST",
            url=f"{self.base_url}/global_api/",
            params={"action": self.route},
            request_body=body,
            headers=req.headers,
        )

# 2. 声明一个基类
@define
class GatewayAPI(BaseAPIObject[T]):
    converter = field(default=GatewayConverter)

# 3. 所有接口继承 GatewayAPI
class GetContainersAPI(GatewayAPI[ContainersResp]): 
    ...

就是这么简单:只需重写 post_prepare这个钩子,其余只需交给框架处理。

🌟 你将获得

  1. 真实度 100% ——完全模拟前端流量,线上巡检 / 烟测再也不用抓包贴代码。
  2. 单源可维护——网关规则变?只改 1 个 Converter,无需重写接口 / 用例。

更多进阶玩法和详细用法👉详见官方文档「高级特性 - 自定义转换器」。

还有更多的特性在此就不再赘述,感兴趣可以前往官方文档进行了解:https://aomaker.cn

六、关于 AI

通过前面的介绍,有没有发现 aomaker 的 AI 含量为 0。

最近一年多以来,似乎任何测试方面的技术,只要不跟 AI 沾边,感觉都不好意思发出来,但是纵观现在公开发表的各类 AI+ 自动化测试技术,看着以为是法拉利,但当真正要去落地应用到工程项目上,发现是个玩具车。(当然,不排除有厉害的团队已经让 AI 真的落地赋能了)

我的观点

1.可靠性与一致性问题,生产式 AI 的输出太黑盒了,同样的输入在不同时间让 AI 生成测试,结果都可能不一致,如果是 agent,在不能保证每个节点准确率是 100% 的情况下,最后出来的结果真的可靠吗?这种不可预期性对严肃的测试工作来说是隐患,可能引入伪阳性或伪阴性结果,最后还是需要人工介入判断处理,反而增加更多成本。

2.维护困难,如果让 AI 大量生成测试用例,随着软件演进,这些用例本身需要更新,而再次调用 AI 批量修改用例仍需验证正确性,相当于增加了一层间接成本。

3.资源与成本问题,一些 AI 增强的测试工具虽然减轻了人工脚本编写,但把部分成本转移到了 GPU 算力或付费 API 上,尤其是现在的 agent+mcp,那 token 用量更是翻倍增长,这种成本阶段下,那不是一般的测试团队玩得起的。

4.测试逻辑依赖领域知识,AI 模型缺乏对特定业务领域的深层理解,容易遗漏业务约束或误判正常/异常输出。这会导致生成的测试不全面,或者报出大量无效缺陷。

AI 在接口测试这一方面的应用,我觉得目前属于 “锦上添花” 而非 “雪中送炭”。

它在减少重复劳动、扩大测试覆盖面方面展示了潜力,例如自动生成大量边界值和异常场景数据​,自动校验响应格式契合规范等​。这些能力可以降低一些人工疏漏和提高效率。

不过,要真正落地到实际大型工程项目,还需要解决上述瓶颈。对于绝大多数团队而言,短期内 AI 更多是提升生产力的工具,尚无法完全取代人工创造力和专业判断。

我现在能做的,就是继续打磨好 aomaker,等大模型继续进化,然后让他学会 aomaker :)

以我经常跟群友说的一句话收尾: 让子弹再飞一会儿~

七、后续规划

1.关于测试平台

其实集成 aomaker V2 的这套测试平台已经在公司项目落地运行 4 年了,走得不是"web 版 postman"那种低代码路线,而是框架和平台完全解耦,自动化用例通过 IDE 编写,同步到代码仓库,平台拉取代码执行。

因为我认为平台的核心职责应该是调度执行 + 统计度量 + 可视化,而不是为了“让不会代码的同学也可以写自动化测试用例”这种伪需求,在平台上写自动化测试。

但是 V2 和平台后端集成的时候不那么方便,所以 aomaker V3 增加了服务化的能力并暴露了一些框架内部接口出来,如获取接口静态数据统计、获取测试进度信息、获取环境配置等,目的就是为了让 aomaker 成为一个独立服务,能够更方便接入测试平台。

V3 的这套接口管理方式,很适合平台化,所以后续可能会考虑开源一个 aomaker 配套的测试平台出来,如果有时间的话 :)

2.关于迭代管理

当接口文档迭代,某个接口增加了一些非必填参数,在框架内进行模型同步时,这个时候用户可能会感知不到这一版迭代具体有哪些改动,因为原来的 case 的接口调用中,即使没传这个非必填参数,也能运行成功。

所以,在文档迭代同步时,可能需要把这些 diff 可视化出来,测试人员才能更有针对性的去做用例迭代。

八、获取资源

aomaker 完全开源,也希望、欢迎更多感兴趣的同行能加入一起共同建设🤝

代码仓库: https://github.com/ae86sen/aomaker

官方站点: https://aomaker.cn

飞书文档: https://ecnncds7p93h.feishu.cn/wiki/XJZrwK3gqimq1rkC3SyczQSDnQc?fromScene=spaceOverview

交流群:
描述文本

作者微信:

描述文本

共收到 1 条回复 时间 点赞
回复内容未通过审核,暂不显示
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册