惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
NISL@THU
NISL@THU
E
Exploit-DB.com RSS Feed
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
K
Kaspersky official blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
S
Schneier on Security
G
GRAHAM CLULEY
The Hacker News
The Hacker News
T
Threat Research - Cisco Blogs
Scott Helme
Scott Helme
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Cyberwarzone
Cyberwarzone
C
CERT Recently Published Vulnerability Notes
T
Tor Project blog
AWS News Blog
AWS News Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
爱范儿
爱范儿
P
Privacy International News Feed
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
S
Securelist
G
Google Developers Blog
The Last Watchdog
The Last Watchdog
Google Online Security Blog
Google Online Security Blog
美团技术团队
F
Fortinet All Blogs
小众软件
小众软件
Recorded Future
Recorded Future
V
Visual Studio Blog
B
Blog RSS Feed
H
Help Net Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
Martin Fowler
Martin Fowler
Latest news
Latest news
Spread Privacy
Spread Privacy
H
Heimdal Security Blog

博客园 - 小海海宁宁

从0到1:使用Schemathesis搭建API自动化测试框架实战 playwright & selenium对Shadow DOM的处理 自动化平台质量体系建设(草稿) 【模板】邮件提测模板 研发测试质量规范(草稿) 自动化框架 - Q&A 自动化框架 - 核心模块使用指南 - Kafka 自动化框架 - 核心模块使用指南 - Kibana 自动化框架 - 核心模块使用指南 - Playwright 自动化框架 - 核心模块使用指南 - API 自动化框架 - 核心功能使用指南 - 动态值生成 自动化框架 - 核心功能使用指南 - 数据处理模块 自动化框架 - 核心功能使用指南 - 数据校验模块 自动化框架 - 核心功能使用指南 - 上下文值传递 自动化框架 - 核心功能使用指南 - 用例过滤Tag使用 自动化框架 - 核心功能使用指南 - Excel测试用例编写 自动化框架 - 核心功能使用指南 - 配置文件使用指南 自动化框架使用说明 - 快速开始 Kibana如何添加可视化看板
OpenAPI规范及自动化用例生成
小海海宁宁 · 2026-03-11 · via 博客园 - 小海海宁宁
  1. 什么是OpenAPI规范

OpenAPI 规范(OAS),是定义一个标准的、与具体编程语言无关的RESTful API的规范。

OpenAPI 规范使得人类和计算机都能在"不接触任何程序源代码和文档、不监控网络通信"的情况下理解一个服务的作用。

简单来说,OpenAPI文档是一份机器可读的“说明书”,详细描述了你的 API 能做什么,包括:

  • 服务器地址
  • 有哪些可用的URL路径
  • 每个路径支持哪些Action(GET, POST, PUT, DELETE 等)
  • 每个Action需要哪些参数(在路径中、查询字符串中、请求头中等)
  • 请求体应该是什么格式
  • 每个响应可能返回的状态码和对应的数据格式

核心价值:一旦你的 API 被定义在一个标准的 OpenAPI 文档中,整个 API 生命周期中的各种工具都可以基于此文档自动完成工作,极大地提高了效率和规范性。

  1. OpenAPI规范术语

  1. OpenAPI 文档

用来定义或描述一个API的YAML(JSON)文档。OpenAPI 文档可以是单个文件也可以被拆分为多个文件,连接的部分由用户自行决定。固定字段:

字段

是否必须

描述

openapi

OPENAPI版本号

info

提供API相关的元数据,如API名称、描述、版本等

servers

Server地址列表

paths

定义API的所有请求路径及Action

components

提供可复用的组件定义,使用$ref引用

security

声明API使用的安全机制

tags

提供更多元数据的一系列标签。

externalDocs

附加文档

  1. 根级别信息

文档的元数据,描述了 API 本身的基本信息。

openapi: 3.0.3  # OpenAPI版本
info:
  title: Agents API       # API的名称
  description: 坐席相关接口
  version: 1.0.0            # API的版本
  contact:
    name: API支持者
    email: icc2.0@msxf.com
servers:
  - url: https://test.example.com/v1  # API的基础地址
    description: test环境服务器
  - url: https://test1.example.com/v1  # AP 的基础地址
    description: test1环境服务器
paths:     # 接下来会定义所有端点
components: # 接下来会定义可重用的组件
tags:
  - name: agents
    description: "坐席相关接口"
  - name: metrics
    description: "指标相关接口"
  1. paths- 路径

OpenAPI文档核心,定义了 API 的所有可用URL以及每个URL支持的请求Action。

paths:
  /agents:
    get:
      summary: 获取坐席列表
      operationId: listAgents
      tags:
        - agents
      parameters: # 参数定义
        - name: limit
          in: query
          description: 返回结果的数量限制
          schema:
            type: integer
            default: 10
      responses: # 响应定义'200':description:成功返回坐席列表content:application/json:schema:type:arrayitems:$ref:'#/components/schemas/Agent'
    post:
      summary: 创建一个新坐席
      operationId: createAgent
      tags:
        - agents
      requestBody: # 请求体定义
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Agent'  # 引用components定义的 Agent模型
      responses: ...   # 响应定义
  /agents/{agentId}:
    get:
      summary: 通过ID获取坐席详情
      operationId: getAgentById
      parameters: # 包含路径参数 {agentId}-name:agentIdin:path# 参数位置:path, query, header, cookierequired:truedescription:坐席的IDschema:type:integer
      responses: ...
  1. components- 组件

  1. 可重用的对象库,用于避免重复定义。

可以在 paths中通过 $ref来引用这些组件。

components:
  schemas:
    Agent:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        status:
          type: string
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: integer
          description: 错误代码
        message:
          type: string
          description: 错误描述
          
  1. 全局通用响应结构体

如 200、400、401、403、404、500等通用响应结构,确保全站错误格式统一。

components:
  responses:
    BadRequest:
      description: 400 Bad Request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalidParams:
              summary: 参数验证失败
              value:
                code: 400
                message: 请求参数无效
    Unauthorized:
      description: 401 Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            tokenExpired:
              summary: Token无效
              value:
                code: 401
                message: 访问令牌已过期
    Forbidden:
      description: 403 Forbidden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            insufficientPermissions:
              summary: 权限不足
              value:
                code: 403
                message: "没有操作权限"
  1. OpenAPI Swagger编辑器

  1. OpenAPI UI搭建

依赖安装:

yarn add express swagger-ui-express swagger-jsdoc yamljs
yarn add --dev nodemon

通过express启动UI服务:

const express = require('express');
const swaggerUi = require('swagger-ui-express');
const YAML = require('yamljs');

const app = express();
const PORT = process.env.PORT || 3000;

// 加载YAML文件
const swaggerDocument = YAML.load('./swagger.yaml');

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

app.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
  console.log(`Swagger文档: http://localhost:${PORT}/api-docs`);
});

本地Swagger UI:

  1. OpenAPI常见规范

  • 路径命名必须使用名词复数形式:资源导向,使用名词而非动词。例如,使用 /users,而不是 /getUsers。
  • 必须正确使用 HTTP 方法:

GET: 查询/获取资源

POST: 创建资源

PUT: 全量更新资源

PATCH: 部分更新资源

DELETE: 删除资源

  • 路径参数必须使用大括号标明:例如 /users/{userId},并在parameters中明确定义 in: path及 required: true。
  • 请求体必须使用 application/json:在 requestBody中指定 content: application/json,并引用定义的 Schema。对于文件上传,需单独使用 multipart/form-data。
  • 必须定义并复用数据模型:所有请求/响应体必须在 components/schemas中定义,并在各处通过 $ref引用,避免重复定义。
  • 模型命名必须使用大驼峰命名法:如 User, CreateUserRequest, UserListResponse。
  • 合理使用枚举:对于固定值的字段(如状态),必须使用 enum明确列出所有可能值。
  • 必须定义全局通用的响应码:在 components/responses中定义如 200、400、401、403、404、500等通用响应结构,确保全站错误格式统一。
  • 每个操作必须包含清晰的摘要和描述:summary简要说明操作,description可提供更详细的上下文或注意事项。
  • 必须为所有操作标记标签:使用 tags对接口进行逻辑分组,便于在生成的文档中分类展示。
  1. OpenAPI优势

  1. 与语言无关的标准化接口描述

OpenAPI 规范使用 YAML 或 JSON 格式来描述 API,这两种格式都是机器可读的。这种标准化的描述方式不依赖于任何编程语言,使得不同的工具和系统能够基于同一份规范进行协作。

  1. 自动生成 API 文档

OpenAPI 规范文件可以自动生成交API 文档(如使用 Swagger UI)。文档不仅展示了 API 的URL、参数、请求和响应示例,还允许开发者直接在浏览器中尝试调用 API。

  1. 提升研发效率

利用OpenAPI生成工具(如 Swagger Codegen、OpenAPI Generator),可以根据规范文件自动生成多种编程语言的客户端和服务器代码。前后端可以基于API文档MOCK调试,可以加速前后端的联调进程,并减少手动编写代码可能引入的错误。

  1. 自动化测试

OpenAPI 规范可以用于生成自动化测试用例,验证 API 的实现是否符合规范。可以基于 OpenAPI 规范自动生成测试用例,对 API 进行属性测试,确保 API 的健壮性。

  1. 生态系统和工具支持

OpenAPI 拥有庞大的生态系统,包括各种工具和库,支持从设计、生成、测试到监控的整个 API 生命周期。这些工具包括:

  • Swagger Editor:用于编辑和预览 OpenAPI 规范。
  • Swagger UI:生成交互式 API 文档。
  • Swagger Codegen:生成客户端和服务器代码。
  • Mock Server:根据规范模拟 API 响应。
  • Schemathesis:生成自动化测试用例
  1. 基于OpenAPI生成自动化用例

  1. Schemathesis介绍

Schemathesis是一个基于属性测试(Property-based Testing)的API测试工具,专门用于测试符合OpenAPI/Swagger规范的Web API。

  1. Schemathesis特点

  1. 属性测试

  • 不同于传统的示例测试,不会提供明确的输入值,不验证明确逻辑。
  • 自动生成大量随机但符合规范的测试数据,包括无效、意外或随机的输入,以测试API的鲁棒性和错误处理能力。
  • 验证 API 的通用属性而非特定场景。
  1. 自动生成测试

基于OpenAPI文档自动生成测试用例,覆盖API的所有端点和参数。

st run --checks all http://api.example.com/openapi.json
  1. 智能断言

  • 响应状态码在定义范围内
  • 响应模式符合 schema
  • 响应内容类型正确
  • 没有服务器错误(500 Server Error)
  1. Schemathesis快速开始

  1. 安装

pip install schemathesis

# 验证安装
schemathesis --version
  1. 准备yaml文件

openapi: 3.0.3
info:
  title: 坐席管理 API
  description: 简单的坐席管理接口示例
  version: 1.0.0
  contact:
    name: API 支持
    email: support@example.com

servers:
  - url: http://localhost:8000/api/v1
    description: 开发服务器
  - url: https://api.example.com/v1
    description: 生产服务器

paths:
  /agents:
    get:
      summary: 获取坐席列表
      description: 获取系统中所有坐席的列表,支持分页和过滤
      operationId: getAgents
      tags:
        - 坐席管理
      parameters:
        - name: page
          in: query
          description: 页码
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
            example: 1
        - name: limit
          in: query
          description: 每页数量
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
            example: 20
        - name: active
          in: query
          description: 过滤活跃坐席
          required: false
          schema:
            type: boolean
            example: true
      responses:
        '200':
          description: 成功获取坐席列表
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      agents:
                        type: array
                        items:
                          $ref: '#/components/schemas/Agent'
                      pagination:
                        $ref: '#/components/schemas/Pagination'
                  message:
                    type: string
                    example: "坐席列表获取成功"
              examples:
                success:
                  summary: 成功响应示例
                  value:
                    success: true
                    data:
                      agents:
                        - id: 1
                          name: "张三"
                          email: "zhangsan@example.com"
                          age: 28
                          active: true
                          createdAt: "2024-01-15T10:30:00Z"
                        - id: 2
                          name: "李四"
                          email: "lisi@example.com"
                          age: 32
                          active: true
                          createdAt: "2024-01-16T14:20:00Z"
                      pagination:
                        page: 1
                        limit: 20
                        total: 2
                        pages: 1
                    message: "坐席列表获取成功"
        '400':
          description: 请求参数错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                invalid-params:
                  summary: 参数错误示例
                  value:
                    success: false
                    error:
                      code: "INVALID_PARAMS"
                      message: "参数验证失败"
                      details:
                        - field: "limit"
                          message: "必须小于或等于100"
                    message: "请求参数无效"
        '500':
          description: 服务器内部错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                server-error:
                  summary: 服务器错误示例
                  value:
                    success: false
                    error:
                      code: "INTERNAL_ERROR"
                      message: "服务器内部错误"
                    message: "系统繁忙,请稍后重试"

components:
  schemas:
    Agent:
      type: object
      required:
        - id
        - name
        - email
      properties:
        id:
          type: integer
          format: int64
          description: 坐席唯一标识
          example: 1
        name:
          type: string
          description: 坐席姓名
          minLength: 1
          maxLength: 50
          example: "张三"
        email:
          type: string
          format: email
          description: 坐席邮箱
          example: "agent@example.com"
        age:
          type: integer
          minimum: 0
          maximum: 150
          description: 坐席年龄
          example: 28
        active:
          type: boolean
          description: 是否活跃
          default: true
          example: true
        createdAt:
          type: string
          format: date-time
          description: 创建时间
          example: "2024-01-15T10:30:00Z"
        updatedAt:
          type: string
          format: date-time
          description: 更新时间
          example: "2024-01-20T08:15:00Z"

    Pagination:
      type: object
      properties:
        page:
          type: integer
          description: 当前页码
          example: 1
        limit:
          type: integer
          description: 每页数量
          example: 20
        total:
          type: integer
          description: 总记录数
          example: 150
        pages:
          type: integer
          description: 总页数
          example: 8

    Error:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              description: 错误代码
              example: "VALIDATION_ERROR"
            message:
              type: string
              description: 错误信息
              example: "参数验证失败"
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                    example: "email"
                  message:
                    type: string
                    example: "必须是有效的邮箱格式"
        message:
          type: string
          description: 坐席友好的错误信息
          example: "请求参数无效"

  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token认证
  1. 本地启动Mock API服务

准备nodejs环境,安装prism

yarn global add @stoplight/prism-cli

# 动态模拟接口返回
prism mock openapi.yaml --dynamic

服务启动后检查API正常返回

  1. 使用Schemathesis测试接口

命令行执行:

schemathesis run openapi.yaml --url=http://127.0.0.1

执行结果:

测试报告生成yaml格式:

schemathesis run openapi.yaml --url=http://127.0.0.1 --report vcr --report-vcr-path ./custom-vcr.yaml

  1. Schemathesis与pytest集成

集成示例:

import schemathesis

schema = schemathesis.openapi.from_path("./openapi.yaml")

@schema.parametrize()
def test_api_code(case):
    print(case)
    response = case.call(url="http://127.0.0.1")
    assert response.status_code is not None
    assert response.status_code != 500

@schema.parametrize()
def test_api_response(case):
    print(case)
    case.call_and_validate(url="http://127.0.0.1")

测试报告: