通过OpenAPI 测试脚本生成器批量生成脚本

1. 概述

OpenAPI 测试生成器 会根据 OpenAPI 3.x 规范生成 API 测试脚本,并将生成出来的测试用例直接注册到 Testany。

ℹ️

当前实现已经切换到与 Import from Git V2 相同的托管 Git mirror 基础模型。使用 OpenAPI Generate 时,您不需要再配置 GitHub 连接、仓库 URL、分支或仓库 Token。

主要优势:

  • 快速生成: 根据 OpenAPI 契约批量生成正向、正向边界和反向测试脚本,显著减少初始编写工作量。
  • 平台托管存储: 生成产物由 Testany 托管到内部 mirror 中,用户不再为这条流程单独维护目标 Git 仓库。
  • 生成记录可追踪: 每次生成都归属于一个生成记录,后续可基于该记录继续更新、复用或删除。
  • 覆盖模型标准化: 生成用例遵循统一的场景模型。完整的场景清单请参阅附录

2. 开始之前

2.1 准备有效的 OpenAPI 文件

  • 当前 UI 使用 本地文件上传
  • 支持 OpenAPI 3.x 及以上版本。
  • 强烈建议先使用 42Crunch 等 API 质量或安全工具对规范进行审计,确保生成基于稳定且可执行的 API 契约。

2.2 选择可用的运行时

  • 每个生成记录都绑定一个 运行时
  • 该运行时就是后续执行生成脚本的目标运行环境。
  • 当前不可用或不健康的运行时会在界面中置灰,无法被选中。

2.3 规划生成记录

  • 生成记录 Name 必须唯一,且创建后不可修改。
  • 后续更新已有记录时,会继续沿用该记录已有的运行时。
  • 生成记录是生成用例生命周期的锚点,后续的更新和删除行为都围绕该记录发生。

3. 创建生成记录

3.1 进入向导

  1. 进入 测试用例库
  2. 点击 注册测试用例 旁边的下拉按钮。
  3. 选择 从 OpenAPI 生成

3.2 创建新记录

步骤 1/2 中,点击 创建新生成记录

3.2.1 配置记录

步骤 2/2 中,填写:

  • 名称: 生成记录名称,创建后不可修改。
  • 运行时: 用于执行生成脚本的目标运行时。
  • OpenAPI 文件: 上传本地 OpenAPI 文件。

文件解析成功后,Testany 会显示确认信息,并允许您继续进入端点选择步骤。

3.2.2 选择端点并生成

解析完成后:

  1. 检查已识别出的 API 端点。
  2. 选择您要生成的端点或路径分组。
  3. 点击 生成测试脚本

生成成功后,成功弹窗会显示已选择端点数量和生成脚本总数,并提供跳转到测试用例库的入口。

3.2.3 查看生成出的测试用例

生成完成后:

  • 生成出的测试用例会出现在测试用例库
  • 平台会把这些用例记录为属于当前生成记录的 OpenAPI 生成用例
  • 您后续应通过生成记录和测试用例库来管理它们,而不是去维护一个用户自有的 Git 分支

3.2.4 理解生成脚本实际存放在哪里

生成的脚本和配套文件会在后台保存到 Testany 托管的 mirror 仓库 中。

这意味着:

  • 向导里不再有仓库 URL 字段
  • 向导里不再有分支字段
  • 向导里不再有仓库凭证字段

从底层实现上看,这条链路已经与 Git V2 的 mirror 模型对齐;但从用户操作上看,OpenAPI Generate 的入口更简单,不需要您先完成额外的 Git 连接配置。

4. 更新或删除生成记录

4.1 更新已有记录

更新已有记录的步骤是:

  1. 步骤 1/2 中选择已有生成记录。
  2. 上传新的本地 OpenAPI 文件。
  3. 检查解析结果,并重新选择需要生成的端点。

更新记录时:

  • 记录原有的名称和运行时保持不变
  • 当前选中的端点会基于最新上传的文件重新生成
  • 之前生成过、但现在被取消选择或已从新版 OpenAPI 中消失的端点,会根据当前使用情况进行处理

对于这些被移除的端点:

  • 如果对应测试用例没有被任何流水线使用,该用例会被删除
  • 如果对应测试用例已经被某条流水线使用,平台会保留该用例以避免破坏流水线,但会解除它与生成记录之间的关联
⚠️

这类“被保留但已解除关联”的用例,如果其原先对应的生成脚本已经从托管 mirror 中移除,后续执行可能失败。更新后请尽快检查并替换这些用例。

4.2 删除生成记录

删除生成记录后,平台会移除该记录与其生成用例之间的关联。

删除后的行为如下:

  • 未被任何测试流水线组装的用例会被永久删除
  • 已被流水线组装的用例会被保留,但会解除与该生成记录的关联

如果您希望这些被保留的用例也一并删除,请先把它们从流水线中移除,再回到测试用例库手动删除。

由于这条流程不再使用用户自有的 Git 仓库,所以删除记录后也不存在需要您手工清理的外部分支或仓库。

5. 常见问题 (FAQ)

问题: 为什么现在看不到仓库 URL、分支和仓库 Token 这些字段了?

💡 回答: 因为 OpenAPI 测试生成器现在已经改为使用 Testany 托管的内部 mirror 仓库。平台负责这条流程的脚本存储和同步,因此终端用户不再需要在向导中提供 Git 仓库信息。

问题: 如果我把某个端点取消选择,或者它在新版 OpenAPI 文件里已经不存在了,会发生什么?

💡 回答: 如果对应测试用例没有被任何流水线使用,它会被删除;如果它已经被某条流水线使用,平台会保留该用例以保证流水线完整性,但会移除它与当前生成记录之间的关联。

问题: 为什么有些生成出来的测试用例删不掉?

💡 回答: 已经被一条或多条流水线组装的生成用例,会受到同样的“流水线完整性保护”规则约束。如果您希望永久删除它们,请先把它们从流水线中移除。

问题: 现在应该怎样更新生成结果?

💡 回答: 复用同一个生成记录,重新上传本地 OpenAPI 文件,并重新选择需要生成的端点即可。不要再按“编辑用户自有 Git 分支”的思路来规划这条流程,因为它已经不再依赖那种模型。

附录

下表列出了Testany生成过程中所有支持的测试场景。对于每个场景,表格详细说明了:

  • 场景ID:测试场景的唯一标识符
  • 字段类型:场景适用的数据类型
  • 场景:正向、负面和正向边界测试用例的描述
  • 必需约束:必须定义的OpenAPI规范约束
  • 跳过条件:不生成该场景的情况
场景 ID字段类型场景描述必要约束条件跳过条件
1.00string符合所有约束条件的有效字符串值
1.01string不符合指定格式的字符串值定义了 format
1.02string不符合指定模式的字符串值定义了 enum
1.03string字符串长度小于 minLength定义了 minLength定义了 enum
1.04stringminLength > 0 时,字符串为空minLength > 0定义了 enum
1.05string字符串长度大于 maxLength定义了 enum
1.06string字符串值不在 enum 列表中定义了 enum
1.07stringnullable 为 false 时,字符串值为 nullnullable=false
1.08string值类型是数字而不是字符串type=string
1.09string值类型是布尔值而不是字符串type=string
1.10string值类型是数组而不是字符串type=string
1.11string值类型是对象而不是字符串type=string
1.21stringpayload 中不存在此字段字段是必需的
1.22string字符串长度刚好等于 minLength定义了 minLength定义了 enum
1.23string字符串长度刚好等于 maxLength定义了 maxLength定义了 enum
2.00integer符合所有约束条件的有效整数值
2.01integer不符合指定格式的整数值定义了 format定义了 enum
2.03integer整数值小于 minimum定义了 minimum定义了 enum
2.05integer整数值大于 maximum定义了 maximum定义了 enum
2.06integer整数值不在 enum 列表中定义了 enum定义了 minimummaximummultipleOf中的任意一个
2.07integernullable 为 false 时,整数值为 nullnullable=false
2.09integer值类型是布尔值而不是整数定义了 format
2.10integer值类型是数组而不是整数定义了 format
2.11integer值类型是对象而不是整数定义了 format
2.12integer值类型是浮点数而不是整数定义了 format
2.13integerexclusiveMinimum 为 true 时,整数值等于 minimumexclusiveMinimum=true定义了 enum
2.15integerexclusiveMaximum 为 true 时,整数值等于 maximumexclusiveMaximum=true定义了 enum
2.16integer整数值不是指定数字的倍数定义了 multipleOf定义了 enumminimummaximum中的任意一个
2.17integer值类型是字符串而不是整数type=integer
2.21integerpayload 中不存在此字段字段是必需的
2.22integer整数值刚好等于 minimum定义了 minimum定义了 enum
2.23integer整数值刚好等于 maximum定义了 maximum定义了 enum
2.24integer整数值刚好大于 minimumexclusiveMinimum=true定义了 enum
2.25integer整数值刚好小于 maximumexclusiveMaximum=true定义了 enum
3.00boolean符合所有约束条件的有效布尔值
3.08boolean值类型是数字而不是布尔值type=boolean
3.10boolean值类型是数组而不是布尔值type=boolean
3.11boolean值类型是对象而不是布尔值type=boolean
3.17boolean值类型是字符串而不是布尔值type=boolean
3.21booleanpayload 中不存在此字段字段是必需的
4.00number符合所有约束条件的有效数值
4.01number不符合指定格式的数值定义了 format定义了 enum
4.03number数值小于 minimum定义了 minimum定义了 enum
4.05number数值大于 maximum定义了 maximum定义了 enum
4.06number数值不在 enum 列表中定义了 enum定义了 minimummaximummultipleOf中的任意一个
4.07numbernullable 为 false 时,数值为 nullnullable=false
4.09number值类型是布尔值而不是数值type=number
4.10number值类型是数组而不是数值type=number
4.11number值类型是对象而不是数值type=number
4.13numberexclusiveMinimum 为 true 时,数值等于 minimumexclusiveMinimum=true定义了 enum
4.15numberexclusiveMaximum 为 true 时,数值等于 maximumexclusiveMaximum=true定义了 enum
4.16number数值不是指定数字的倍数定义了 multipleOf定义了 enum、minimum、maximum中的任意一个
4.17number值类型是字符串而不是数值type=number
4.21numberpayload 中不存在此字段字段是必需的
4.22number数值刚好等于 minimum定义了 minimum定义了 enum
4.23number数值刚好等于 maximum定义了 maximum定义了 enum
4.24number数值刚好大于 minimumexclusiveMinimum=true定义了 enum
4.25number数值刚好小于 maximumexclusiveMaximum=true定义了 enum
5.00array符合所有约束条件的有效数组值
5.03array数组长度小于 minItems定义了 minItems
5.04arrayminItems > 0 时,数组为空minItems > 0
5.05array数组长度大于 maxItems
5.07arraynullable 为 false 时,数组值为 nullnullable=false
5.08array值类型是数字而不是数组type=array
5.09array值类型是布尔值而不是数组type=array
5.11array值类型是对象而不是数组type=array
5.17array值类型是字符串而不是数组type=array
5.18arrayuniqueItems 为 true 时,数组包含重复项uniqueItems=true
5.21arraypayload 中不存在此字段字段是必需的
6.00object符合所有约束条件的有效对象值
6.03object对象属性数量小于 minProperties定义了 minProperties
6.04objectminProperties > 0 时,对象为空minProperties > 0
6.05object对象属性数量大于 maxProperties定义了 maxProperties
6.07objectnullable 为 false 时,对象值为 nullnullable=false
6.08object值类型是数字而不是对象type=object
6.09object值类型是布尔值而不是对象type=object
6.10object值类型是数组而不是对象type=object
6.17object值类型是字符串而不是对象type=object
6.19object对象缺少必需属性属性是必需的
6.20objectadditionalProperties 为 false 时,对象包含额外属性additionalProperties=false
6.21objectpayload 中不存在此字段字段是必需的
6.22object对象属性数量刚好等于 minProperties定义了 minProperties
6.23object对象属性数量刚好等于 maxProperties定义了 maxProperties

test_post_pet_petId_negative_body_status.py为例:

如果 POST /pet/{petId} 请求体中 status 字段的 OpenAPI 定义是带有特定约束(例如,一个 enum)的字符串,则生成的脚本 test_post_pet_petId_negative_body_status.py 将包含根据这些约束而适用的上述表格中的场景测试。例如,如果 status 被定义为一个字符串枚举,那么场景 1.02(不符合模式,如果定义了模式)、1.05(长度大于 maxLength,如果定义了 maxLength)、1.06(不在 enum 列表中),以及类型不匹配(1.08、1.09、1.10、1.11)等都可能被生成,前提是存在相关的约束。

还有疑问?

我们的团队随时为您服务。欢迎联系我们,我们会尽快回复。