Add your description here
Project description
🚀 API-SOS
API-SOS 是一个用于 API 测试的工具,它可以从 OpenAPI 规范生成测试用例,并支持记录和验证 API 响应。
📦 安装
pip install api-sos
🚀 快速开始
📚 作为 Python 库使用
API-SOS 既可以通过命令行使用,也可以作为库直接集成到你的代码中。作为库调用时,它不会主动 sys.exit(1),而是返回结果,你可以自行决定如何处理错误或失败。
✅ 基础示例:运行已生成的用例
import asyncio
from api_sos import has_failures, run_checks
async def main() -> None:
results = await run_checks(
"output.yaml",
concurrent=5,
endpoint="http://localhost:8000",
variables="vars.yaml",
interactive=False,
verbose=True,
)
if has_failures(results):
# 这里由你决定如何处理失败,例如抛出异常或返回错误码
raise RuntimeError("API checks failed")
asyncio.run(main())
✅ 生成用例并写入文件
import asyncio
from api_sos import generate_checks
async def main() -> None:
await generate_checks(
"openapi.yaml",
"output.yaml",
endpoint="http://localhost:8000",
concurrent=3,
headers="headers.yaml",
headers_variables="vars.yaml",
no_record=False,
no_example=False,
verbose=True,
)
asyncio.run(main())
🔍 直接使用底层运行函数
如果你想完全掌控运行过程(比如批量处理多个 Input),可以直接调用 api_sos.run:
import asyncio
from api_sos import Input, run
async def main() -> None:
input_ = Input.load("output.yaml")
results = await run(input_, concurrent=2, variables={"token": "xxx"})
# results 是 CheckResult 或 Exception 的列表
asyncio.run(main())
🎯 生成测试用例
从 OpenAPI 规范生成测试用例:
# 指定端点并记录响应
api-sos generate openapi.yaml output.yaml --endpoint http://localhost:8000
# 使用并发请求记录响应
api-sos generate openapi.yaml output.yaml --endpoint http://localhost:8000 --concurrent 5
# 使用自定义请求头
api-sos generate openapi.yaml output.yaml --headers headers.yaml --endpoint http://localhost:8000
# 使用带模板变量的请求头(secretes场景)
api-sos generate openapi.yaml output.yaml --headers headers.yaml --headers-variables vars.yaml --endpoint http://localhost:8000
# 跳过响应记录
api-sos generate openapi.yaml output.yaml --no-record
# 跳过从示例生成检查
api-sos generate openapi.yaml output.yaml --no-example --endpoint http://localhost:8000
▶️ 运行测试
运行生成的测试用例:
# 基本用法
api-sos run output.yaml
# 使用并发执行
api-sos run output.yaml --concurrent 5
# 指定端点
api-sos run output.yaml --endpoint http://localhost:8000
# 使用变量替换
api-sos run output.yaml --variables vars.yaml
# 交互式编辑
api-sos run output.yaml --interactive
🔄 交互式编辑模式
当使用--interactive或-i参数运行测试时,如果检查结果与预期不符(存在差异),系统会自动打开编辑器让你修改断言:
# 启用交互式编辑模式
api-sos run output.yaml -i
# 使用自定义编辑器(通过环境变量设置)
EDITOR=vim api-sos run output.yaml -i
交互式编辑工作流程
-
当检测到断言与实际结果不匹配时,系统会打开你的编辑器
-
编辑器中会显示以下内容:
assert: 当前的断言内容,你可以修改这部分actual: 实际响应内容(仅供参考,保存时会被丢弃)name: 检查项名称(仅供参考,保存时会被丢弃)- 使用说明
-
你可以:
- 从
actual部分复制值到assert部分 - 修改断言中的特定字段
- 使用Jinja2模板表达式创建动态断言,如
{{ actual|is_type('int') }}
- 从
-
保存并退出编辑器后,修改将自动应用到原始文件中
这种交互式方式非常适合初始测试开发和调试过程。
📝 配置文件示例
所有配置的文件名可以是任意名称,请通过命令的参数进行传递
🔑 请求头配置 (headers.yaml) 在调用generate时,这部分请求头会自动被插入到生成的结构中
Authorization: Bearer {{token}}
Content-Type: application/json
X-Custom-Header: xxx
🔄 变量配置 (vars.yaml)
token: "your-token-here"
custom_value: "test"
✅ 测试用例配置 (output.yaml)
version: "1.0.0"
endpoint: "http://localhost:8000"
checks:
- name: "Get User"
pathname: "/api/users/1"
method: "GET"
# 可选:用于在 diff 结果中标记标签
tags: ["user", "smoke"]
headers:
Authorization: "Bearer {{token}}"
assert_:
http_status: 200
content:
id: 1
name: "John Doe"
✨ 功能特性
- 从 OpenAPI 规范自动生成测试用例
- 支持记录和验证 API 响应
- 支持并发请求
- 支持请求头模板变量
- 支持变量替换
- 支持交互式编辑
- 支持自定义端点
- 支持多种 HTTP 方法(GET, POST, PUT, DELETE 等)
- 灵活的响应断言系统
- 支持 Jinja2 模板表达式
- 内置丰富的断言过滤器
- 支持代理和认证
- 支持超时配置
🔧 高级用法
🎯 断言系统
🎨 支持的过滤器
matches(pattern): 正则表达式匹配contains(substr): 包含子字符串gt(other): 大于lt(other): 小于gte(other): 大于等于lte(other): 小于等于ne(other): 不等于is_numeric(): 是否为数字is_date(): 是否为日期格式is_email(): 是否为邮箱格式length(): 获取长度starts_with(prefix): 是否以指定字符串开头ends_with(suffix): 是否以指定字符串结尾in_range(min_val, max_val): 是否在指定范围内is_empty(): 是否为空is_type(expected_type): 检查值是否为指定的 Python 类型(如 'str', 'int', 'float', 'list', 'dict' 等)
📊 上下文变量
在表达式中可以使用以下变量:
actual: 当前字段的实际值response: 整个响应对象status: HTTP 状态码headers: 响应头body: 响应体
📋 高级配置示例
🔄 使用变量
version: "1.0.0"
endpoint: "https://api.example.com"
variables:
min_age: 18
valid_status: ["active", "pending"]
checks:
- name: "创建用户"
pathname: "/users"
method: POST
payload:
value:
name: "test_user"
email: "test@example.com"
assert:
http_status: 201
content:
age: "{{ actual|gte(min_age) }}"
status: "{{ actual in valid_status }}"
🌐 代理设置
checks:
- name: "使用代理"
pathname: "/api"
method: GET
proxy: "http://proxy.example.com:8080"
proxy_auth:
login: "user"
password: "pass"
⏱️ 超时设置
checks:
- name: "设置超时"
pathname: "/api"
method: GET
timeout:
total: 30
connect: 10
sock_read: 20
🎯 复杂断言示例
checks:
- name: "复杂断言示例"
pathname: "/orders"
method: POST
assert:
http_status: 201
content:
# 使用多个条件
is_valid: "{{ actual.amount >= 100 and actual.status in ['pending', 'processing'] }}"
# 使用过滤器链
is_valid_email: "{{ actual.email|is_email and actual.email|contains('@example.com') }}"
# 使用范围检查
is_valid_amount: "{{ actual.amount|in_range(100, 1000) }}"
# 使用正则表达式
is_valid_date: "{{ actual.created_at|matches('^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$') }}"
🛠️ 开发
# 安装开发依赖
uv sync --dev
# 运行代码格式化
black src
isort src
📄 许可证
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file api_sos-1.3.0-py3-none-any.whl.
File metadata
- Download URL: api_sos-1.3.0-py3-none-any.whl
- Upload date:
- Size: 22.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60c8ae5d48a4c456b92d4804e02e399615a5d2686f4d956fd54ff67ad10b5a04
|
|
| MD5 |
40db832ac22d3ade2435a89bdce84380
|
|
| BLAKE2b-256 |
a835e5a7555fff323adf740abdf912efd45f507db5a45ddbdd99377ecf240e8a
|