API 测试套件构建器

api-test-suite-builder
分类编程
作者Alireza Rezvani
许可MIT
评分4.80/5
使用16.1K

API 测试套件构建器 (API Test Suite Builder)

级别: POWERFUL (强大)
类别: Engineering (工程)
领域: Testing / API Quality (测试 / API 质量)

---

概述

扫描跨框架的 API 路由定义(Next.js App Router, Express, FastAPI, Django REST),并自动生成涵盖身份验证、输入验证、错误代码、分页、文件上传和速率限制的全面测试套件。输出可直接运行的测试文件,支持 Vitest+Supertest (Node) 或 Pytest+httpx (Python)。

---

核心能力

  • 路由检测 — 扫描源文件以提取所有 API 端点
  • 鉴权覆盖 — 有效/无效/过期令牌,缺失鉴权请求头
  • 输入验证 — 缺失字段、类型错误、边界值、注入尝试
  • 错误代码矩阵 — 为每个路由测试 400/401/403/404/422/500 状态码
  • 分页测试 — 首页/末页/空页/超大页
  • 文件上传 — 有效文件、超大文件、错误 MIME 类型、空文件
  • 速率限制 — 突发流量检测、单用户限制 vs 全局限制

---

使用场景

  • 新增 API — 在编写实现之前生成测试脚手架 (TDD)
  • 缺乏测试的遗留 API — 扫描并生成基础覆盖率
  • API 契约审查 — 验证现有测试是否与当前路由定义一致
  • 发布前回归检查 — 确保所有路由至少通过冒烟测试
  • 安全审计准备 — 生成对抗性输入测试

---

路由检测

Next.js App Router

bash
# 查找所有路由处理程序
find ./app/api -name "route.ts" -o -name "route.js" | sort

从每个路由文件中提取 HTTP 方法

grep -rn "export async function\|export function" app/api/**/route.ts | \ grep -oE "(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)" | sort -u

完整路由映射

find ./app/api -name "route.ts" | while read f; do route=$(echo $f | sed 's|./app||' | sed 's|/route.ts||') methods=$(grep -oE "export (async )?function (GET|POST|PUT|PATCH|DELETE)" "$f" | \ grep -oE "(GET|POST|PUT|PATCH|DELETE)") echo "$methods $route" done

Express

bash
# 查找所有路由文件
find ./src -name "*.ts" -o -name "*.js" | xargs grep -l "router\.\(get\|post\|put\|delete\|patch\)" 2>/dev/null

提取路由及其行号

grep -rn "router\.\(get\|post\|put\|delete\|patch\)\|app\.\(get\|post\|put\|delete\|patch\)" \ src/ --include="*.ts" | grep -oE "(get|post|put|delete|patch)\(['\"][^'\"]*['\"]"

生成路由映射

grep -rn "router\.\|app\." src/ --include="*.ts" | \ grep -oE "\.(get|post|put|delete|patch)\(['\"][^'\"]+['\"]" | \ sed "s/\.\(.*\)('\(.*\)'/\U\1 \2/"

FastAPI

bash
# 查找所有路由装饰器
grep -rn "@app\.\|@router\." . --include="*.py" | \
  grep -E "@(app|router)\.(get|post|put|delete|patch)"

提取路径和函数名

grep -rn "@\(app\|router\)\.\(get\|post\|put\|delete\|patch\)" . --include="*.py" | \ grep -oE "@(app|router)\.(get|post|put|delete|patch)\(['\"][^'\"]*['\"]"

Django REST Framework

bash
# 提取 urlpatterns
grep -rn "path\|re_path\|url(" . --include="*.py" | grep "urlpatterns" -A 50 | \
  grep -E "path\(['\"]" | grep -oE "['\"][^'\"]+['\"]" | head -40

ViewSet 路由注册

grep -rn "router\.register\|DefaultRouter\|SimpleRouter" . --include="*.py"

---

测试生成模式

鉴权测试矩阵

针对每个需要身份验证的端点,生成:

| 测试用例 | 预期状态码 |
|-----------|------------|
---------------|
| 无 Authorization 请求头 | 401 |
| Token 格式无效 | 401 |
| Token 有效,但用户角色错误 | 403 |
| JWT Token 已过期 | 401 |
| Token 有效且角色正确 | 2xx |
| Token 属于已删除用户 | 401 |

输入验证矩阵

针对所有带有请求体的 POST/PUT/PATCH 接口:

| 测试用例 | 预期状态码 |
|-----------|----------------|
| 空请求体 {} | 400 或 422 |
| 缺失必填字段(逐一测试) | 400 或 422 |
| 类型错误(例如:预期 int 但传入 string) | 400 或 422 |
| 边界值:最小值 - 1 | 400 或 422 |
| 边界值:最小值 | 2xx |
| 边界值:最大值 | 2xx |
| 边界值:最大值 + 1 | 400 或 422 |
| 字符串字段包含 SQL 注入 | 400 或 200 (已过滤) |
| 字符串字段包含 XSS 载荷 | 400 或 200 (已过滤) |
| 必填字段为 Null 值 | 400 或 422 |

---

测试文件示例

→ 详情请参阅 references/example-test-files.md

根据路由扫描生成测试

在获得代码库后,请遵循以下流程:

1. 扫描路由:使用上述检测命令。
2. 阅读每个路由处理器以了解:
- 预期的请求体 Schema
- 鉴权要求(中间件、装饰器)
- 返回类型和状态码
- 业务规则(所有权、角色检查)
3. 生成测试文件:根据上述模式,为每个路由组生成对应的测试文件。
4. 使用描述性命名:例如 "returns 401 when token is expired" 而非 "auth test 3"
5. 使用 Factory/Fixture 生成测试数据 —— 严禁硬编码 ID。
6. 断言响应结构,而不仅仅是状态码。

---

常见陷阱

  • 仅测试正向路径 (Happy Paths) —— 80% 的 Bug 存在于错误路径中,应优先测试这些路径。
  • 硬编码测试数据 ID —— 请使用 Factory/Fixture,因为 ID 在不同环境下会发生变化。
  • 测试间共享状态 —— 务必在 afterEach/afterAll 中进行清理。
  • 测试实现而非行为 —— 测试 API 返回的结果,而非其内部实现方式。
  • 缺失边界测试 —— 分页和限制(limits)中极易出现“差一错误 (off-by-one errors)”。
  • 未测试 Token 过期 —— 过期 Token 的行为与无效 Token 不同。
  • 忽略 Content-Type —— 测试 API 是否会拒绝错误的 Content-Type(例如:预期 JSON 但传入 XML)。

---

最佳实践

1. 每个端点使用一个 describe 块 —— 保持失败用例的隔离性和可读性。
2. 注入最小化数据 —— 不要加载整个数据库,仅创建测试所需的数据。
3. 共享设置使用 beforeAll,清理使用 afterAll —— 避免在 beforeEach 中执行高开销操作。
4. 断言具体的错误消息/字段,而不仅仅是状态码。
5. 验证敏感字段(如密码、密钥)绝不会出现在响应中。
6. 对于鉴权测试,务必将“缺失请求头”与“Token 无效”分开测试。
7. 最后添加频率限制 (Rate Limit) 测试 —— 避免在并行运行时干扰其他测试套件。