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

古一 · April 29, 2025 · Last by qianqianyinchang replied at November 11, 2025 · 35510 hits
本帖已被设为精华帖!

一、前言

一转眼,距离上次在社区发 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

交流群:
描述文本

作者微信:

描述文本

共收到 26 条回复 时间 点赞

只关注于 swagger 文档 对单接口进行测试吗 那么这个工具挺好的 不知道处理时间等参数怎么样 明天我试试这个工具

接口更新之后对应的测试代码的更新维护是怎么处理的?

恒温 将本帖设为了精华贴 30 Apr 09:55
古一 #5 · April 30, 2025 Author
难以怀瑾 回复

单接口或者场景串联都是可以的,标准化积木有了,怎么搭都可以

古一 #6 · April 30, 2025 Author
恒温 回复

正如 todo 所说,目前每次同步接口文档,没法感知到版本迭代变化,所以在考虑做一个迭代时的可视化 schema diff 精准定位变更,然后对用例影响范围和用例迭代变更可能还是需要人工介入判断(自动推导用例层的变更可能需要花点功夫,目前还没细想,may be AST or AI?),同时用例层的设计还是要有足够的分层抽象,降低变更影响。

恒温 回复

+1 关键点在这块,如果不自动去同步更新 那其实写了一个转换模板的工具。维护成本还是在的,如果是同步更新又怎么确认返回结构,参数,断言这些呢。

关于平台化考虑过使用 jupyter notebook 吗

古一 #9 · April 30, 2025 Author
Vanessa 回复

什么思路


楼主 swagger json 报错了 我直接跳过有影响吗

楼主,看了下,还是需要写 testcase,能不能直接通过,参数类型和限制直接生成假数据和测试用例,单接口测试只关心接口状态码是不是 200,返回值的数据结构是不是符合 jsonschema,每次执行 swagger 的单接口测试时重新生成一份 apis、model 和 testcase,这样就不怕接口更新了,还有arun -e mock -m mock_api这些参数没说明不是很友好-m mock_api大概猜出来了 选择标记数据。

古一 #12 · May 06, 2025 Author
难以怀瑾 回复

可以的,是下一个版本的 feature

虽然但是,我感觉 pydantic 已经很好用了。回去研究研究这个 attrs

古一 #16 · May 09, 2025 Author

pydantic 很好,只是在接口自动化这个场景,attrs 更轻更适合。

入群二维码过期了,怎么入群交流

古一 #18 · May 12, 2025 Author
Nick 回复

加我 v,拉你

NotBBB · #19 · June 19, 2025
Author only
古一 #20 · June 24, 2025 Author
NotBBB 回复

文末有码,扫一下

是否支持多域名配置和多域名登录,涉及到多个系统联合测试的情况

古一 #22 · July 15, 2025 Author
gungnir 回复

of course

参考 schema 这部分可不可以加点东西呢,对于接口来说大多数字段在每次迭代其实是不变更的,那么是不是可以把上次成功的返回 json 存到库里或者一个缓存里面,新的接口执行返回和上次的一致代表通过,返回的 json 部分可以把带有随机值和可预料会变更的字段(系统时间等等)抽离出来不做比对,这样就不用自己去写用例断言了

古一 #24 · July 31, 2025 Author
LYC 回复

现在就这样的呀,schema 的断言是自动的

古一 回复

这只是数据类型和必填项等的校验吧

文档格式舒适,但是一圈对比下来还是可视化编排的 Apifox 更香

非常好。

面对市面上无数个接口自动化平台,还有专业的接口测试工具,如 ApiPost,ApiFox,有何优势呢?

目前是还不支持 SWAGGER 3.0 是么?大概什么时候可以支持 SWAGGER 3.0 呢?

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up