---
title: "通过OpenAPI 测试脚本生成器批量生成脚本"
language: "zh"
url: "https://docs.testany.io/zh/docs/generating-test-cases-by-openapi-test-generator/"
markdown_url: "https://docs.testany.io/zh/docs/generating-test-cases-by-openapi-test-generator.md"
translation: "https://docs.testany.io/en/docs/generating-test-cases-by-openapi-test-generator.md"
last_updated: "2026-04-20T15:53:41+08:00"
---

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

## 1. **概述**

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


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


主要优势：

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

## 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.00 | string | 符合所有约束条件的有效字符串值 |  |  |
| 1.01 | string | 不符合指定格式的字符串值 | 定义了 `format` |  |
| 1.02 | string | 不符合指定模式的字符串值 |  | 定义了 `enum` |
| 1.03 | string | 字符串长度小于 `minLength` | 定义了 `minLength` | 定义了 `enum` |
| 1.04 | string | `minLength` > 0 时，字符串为空 | `minLength > 0` | 定义了 `enum` |
| 1.05 | string | 字符串长度大于 `maxLength` |  | 定义了 `enum` |
| 1.06 | string | 字符串值不在 `enum` 列表中 | 定义了 enum |  |
| 1.07 | string | `nullable` 为 false 时，字符串值为 null | `nullable=false` |  |
| 1.08 | string | 值类型是数字而不是字符串 | `type=string` |  |
| 1.09 | string | 值类型是布尔值而不是字符串 | `type=string` |  |
| 1.10 | string | 值类型是数组而不是字符串 | `type=string` |  |
| 1.11 | string | 值类型是对象而不是字符串 | `type=string` |  |
| 1.21 | string | payload 中不存在此字段 | 字段是必需的 |  |
| 1.22 | string | 字符串长度刚好等于 `minLength` | 定义了 `minLength` | 定义了 `enum` |
| 1.23 | string | 字符串长度刚好等于 `maxLength` | 定义了 `maxLength` | 定义了 `enum` |
| 2.00 | integer | 符合所有约束条件的有效整数值 |  |  |
| 2.01 | integer | 不符合指定格式的整数值 | 定义了 `format` | 定义了 `enum` |
| 2.03 | integer | 整数值小于 `minimum` | 定义了 `minimum` | 定义了 `enum` |
| 2.05 | integer | 整数值大于 `maximum` | 定义了 `maximum` | 定义了 `enum` |
| 2.06 | integer | 整数值不在 `enum` 列表中 | 定义了 `enum` | 定义了 `minimum`、`maximum`、`multipleOf`中的任意一个 |
| 2.07 | integer | `nullable` 为 false 时，整数值为 null | `nullable=false` |  |
| 2.09 | integer | 值类型是布尔值而不是整数 | 定义了 `format` |  |
| 2.10 | integer | 值类型是数组而不是整数 | 定义了 `format` |  |
| 2.11 | integer | 值类型是对象而不是整数 | 定义了 `format` |  |
| 2.12 | integer | 值类型是浮点数而不是整数 | 定义了 `format` |  |
| 2.13 | integer | `exclusiveMinimum` 为 true 时，整数值等于 minimum | `exclusiveMinimum=true` | 定义了 `enum` |
| 2.15 | integer | `exclusiveMaximum` 为 true 时，整数值等于 maximum | `exclusiveMaximum=true` | 定义了 `enum` |
| 2.16 | integer | 整数值不是指定数字的倍数 | 定义了 `multipleOf` | 定义了 `enum`、`minimum`、`maximum`中的任意一个 |
| 2.17 | integer | 值类型是字符串而不是整数 | `type=integer` |  |
| 2.21 | integer | payload 中不存在此字段 | 字段是必需的 |  |
| 2.22 | integer | 整数值刚好等于 `minimum` | 定义了 `minimum` | 定义了 `enum` |
| 2.23 | integer | 整数值刚好等于 `maximum` | 定义了 `maximum` | 定义了 `enum` |
| 2.24 | integer | 整数值刚好大于 `minimum` | `exclusiveMinimum=true` | 定义了 `enum` |
| 2.25 | integer | 整数值刚好小于 `maximum` | `exclusiveMaximum=true` | 定义了 `enum` |
| 3.00 | boolean | 符合所有约束条件的有效布尔值 |  |  |
| 3.08 | boolean | 值类型是数字而不是布尔值 | `type=boolean` |  |
| 3.10 | boolean | 值类型是数组而不是布尔值 | `type=boolean` |  |
| 3.11 | boolean | 值类型是对象而不是布尔值 | `type=boolean` |  |
| 3.17 | boolean | 值类型是字符串而不是布尔值 | `type=boolean` |  |
| 3.21 | boolean | payload 中不存在此字段 | 字段是必需的 |  |
| 4.00 | number | 符合所有约束条件的有效数值 |  |  |
| 4.01 | number | 不符合指定格式的数值 | 定义了 `format` | 定义了 `enum` |
| 4.03 | number | 数值小于 `minimum` | 定义了 `minimum` | 定义了 `enum` |
| 4.05 | number | 数值大于 `maximum` | 定义了 `maximum` | 定义了 `enum` |
| 4.06 | number | 数值不在 `enum` 列表中 | 定义了 `enum` | 定义了 `minimum`、`maximum`、`multipleOf`中的任意一个 |
| 4.07 | number | `nullable` 为 false 时，数值为 null | `nullable=false` |  |
| 4.09 | number | 值类型是布尔值而不是数值 | `type=number` |  |
| 4.10 | number | 值类型是数组而不是数值 | `type=number` |  |
| 4.11 | number | 值类型是对象而不是数值 | `type=number` |  |
| 4.13 | number | `exclusiveMinimum` 为 true 时，数值等于 minimum | `exclusiveMinimum=true` | 定义了 `enum` |
| 4.15 | number | `exclusiveMaximum` 为 true 时，数值等于 maximum | `exclusiveMaximum=true` | 定义了 `enum` |
| 4.16 | number | 数值不是指定数字的倍数 | 定义了 `multipleOf` | `定义了 enum、minimum、maximum中的任意一个` |
| 4.17 | number | 值类型是字符串而不是数值 | `type=number` |  |
| 4.21 | number | payload 中不存在此字段 | 字段是必需的 |  |
| 4.22 | number | 数值刚好等于 `minimum` | 定义了 `minimum` | 定义了 `enum` |
| 4.23 | number | 数值刚好等于 `maximum` | 定义了 `maximum` | 定义了 `enum` |
| 4.24 | number | 数值刚好大于 `minimum` | `exclusiveMinimum=true` | 定义了 `enum` |
| 4.25 | number | 数值刚好小于 `maximum` | `exclusiveMaximum=true` | 定义了 `enum` |
| 5.00 | array | 符合所有约束条件的有效数组值 |  |  |
| 5.03 | array | 数组长度小于 `minItems` | 定义了 `minItems` |  |
| 5.04 | array | `minItems` > 0 时，数组为空 | `minItems > 0` |  |
| 5.05 | array | 数组长度大于 `maxItems` |  |  |
| 5.07 | array | `nullable` 为 false 时，数组值为 null | `nullable=false` |  |
| 5.08 | array | 值类型是数字而不是数组 | `type=array` |  |
| 5.09 | array | 值类型是布尔值而不是数组 | `type=array` |  |
| 5.11 | array | 值类型是对象而不是数组 | `type=array` |  |
| 5.17 | array | 值类型是字符串而不是数组 | `type=array` |  |
| 5.18 | array | `uniqueItems` 为 true 时，数组包含重复项 | `uniqueItems=true` |  |
| 5.21 | array | payload 中不存在此字段 | 字段是必需的 |  |
| 6.00 | object | 符合所有约束条件的有效对象值 |  |  |
| 6.03 | object | 对象属性数量小于 `minProperties` | 定义了 `minProperties` |  |
| 6.04 | object | `minProperties` > 0 时，对象为空 | `minProperties > 0` |  |
| 6.05 | object | 对象属性数量大于 `maxProperties` | 定义了 `maxProperties` |  |
| 6.07 | object | `nullable` 为 false 时，对象值为 null | `nullable=false` |  |
| 6.08 | object | 值类型是数字而不是对象 | `type=object` |  |
| 6.09 | object | 值类型是布尔值而不是对象 | `type=object` |  |
| 6.10 | object | 值类型是数组而不是对象 | `type=object` |  |
| 6.17 | object | 值类型是字符串而不是对象 | `type=object` |  |
| 6.19 | object | 对象缺少必需属性 | 属性是必需的 |  |
| 6.20 | object | `additionalProperties` 为 false 时，对象包含额外属性 | `additionalProperties=false` |  |
| 6.21 | object | payload 中不存在此字段 | 字段是必需的 |  |
| 6.22 | object | 对象属性数量刚好等于 `minProperties` | 定义了 `minProperties` |  |
| 6.23 | object | 对象属性数量刚好等于 `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）等都可能被生成，前提是存在相关的约束。

## 本页术语

- [测试脚本 (Test Script)](https://docs.testany.io/zh/docs/glossary.md#test-script)
- [运行时 (Runtime)](https://docs.testany.io/zh/docs/glossary.md#runtime)
- [测试用例库（Test Case Library）](https://docs.testany.io/zh/docs/glossary.md#test-case-library)
- [测试用例 (Test Case)](https://docs.testany.io/zh/docs/glossary.md#test-case)
- [测试流水线 (Test Pipeline)](https://docs.testany.io/zh/docs/glossary.md#test-pipeline)
