api-test-suite-builder
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAPI Test Suite Builder
API测试套件构建工具
Tier: POWERFUL
Category: Engineering
Domain: Testing / API Quality
Tier: POWERFUL
Category: Engineering
Domain: Testing / API Quality
Overview
概述
Scans API route definitions across frameworks (Next.js App Router, Express, FastAPI, Django REST) and
auto-generates comprehensive test suites covering auth, input validation, error codes, pagination, file
uploads, and rate limiting. Outputs ready-to-run test files for Vitest+Supertest (Node) or Pytest+httpx
(Python).
扫描多种框架(Next.js App Router、Express、FastAPI、Django REST)的API路由定义,自动生成涵盖认证、输入验证、错误码、分页、文件上传和速率限制的全面测试套件。输出可直接运行的测试文件,支持Vitest+Supertest(Node)或Pytest+httpx(Python)。
Core Capabilities
核心能力
- Route detection — scan source files to extract all API endpoints
- Auth coverage — valid/invalid/expired tokens, missing auth header
- Input validation — missing fields, wrong types, boundary values, injection attempts
- Error code matrix — 400/401/403/404/422/500 for each route
- Pagination — first/last/empty/oversized pages
- File uploads — valid, oversized, wrong MIME type, empty
- Rate limiting — burst detection, per-user vs global limits
- 路由检测 — 扫描源文件提取所有API端点
- 认证覆盖 — 有效/无效/过期令牌、缺失认证头
- 输入验证 — 缺失字段、错误类型、边界值、注入尝试
- 错误码矩阵 — 每个路由覆盖400/401/403/404/422/500错误
- 分页测试 — 首页/末页/空页/超出范围页面
- 文件上传测试 — 有效文件、超大文件、错误MIME类型、空文件
- 速率限制测试 — 突发请求检测、用户级与全局限制
When to Use
使用场景
- New API added — generate test scaffold before writing implementation (TDD)
- Legacy API with no tests — scan and generate baseline coverage
- API contract review — verify existing tests match current route definitions
- Pre-release regression check — ensure all routes have at least smoke tests
- Security audit prep — generate adversarial input tests
- 新增API时 — 在编写实现前生成测试脚手架(测试驱动开发TDD)
- 无测试的遗留API — 扫描并生成基础测试覆盖
- API契约评审 — 验证现有测试是否匹配当前路由定义
- 发布前回归检查 — 确保所有路由至少有冒烟测试
- 安全审计准备 — 生成对抗性输入测试
Route Detection
路由检测
Next.js App Router
Next.js App Router
bash
undefinedbash
undefinedFind all route handlers
查找所有路由处理器
find ./app/api -name "route.ts" -o -name "route.js" | sort
find ./app/api -name "route.ts" -o -name "route.js" | sort
Extract HTTP methods from each route file
从每个路由文件中提取HTTP方法
grep -rn "export async function|export function" app/api/**/route.ts |
grep -oE "(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)" | sort -u
grep -oE "(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)" | sort -u
grep -rn "export async function|export function" app/api/**/route.ts |
grep -oE "(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)" | sort -u
grep -oE "(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)" | sort -u
Full route map
完整路由映射
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
grep -oE "(GET|POST|PUT|PATCH|DELETE)") echo "$methods $route" done
undefinedfind ./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
grep -oE "(GET|POST|PUT|PATCH|DELETE)") echo "$methods $route" done
undefinedExpress
Express
bash
undefinedbash
undefinedFind all router files
查找所有路由文件
find ./src -name ".ts" -o -name ".js" | xargs grep -l "router.(get|post|put|delete|patch)" 2>/dev/null
find ./src -name ".ts" -o -name ".js" | xargs grep -l "router.(get|post|put|delete|patch)" 2>/dev/null
Extract routes with line numbers
提取带行号的路由
grep -rn "router.(get|post|put|delete|patch)|app.(get|post|put|delete|patch)"
src/ --include=".ts" | grep -oE "(get|post|put|delete|patch)(['"][^'"]['"]"
src/ --include=".ts" | grep -oE "(get|post|put|delete|patch)(['"][^'"]['"]"
grep -rn "router.(get|post|put|delete|patch)|app.(get|post|put|delete|patch)"
src/ --include=".ts" | grep -oE "(get|post|put|delete|patch)(['"][^'"]['"]"
src/ --include=".ts" | grep -oE "(get|post|put|delete|patch)(['"][^'"]['"]"
Generate route map
生成路由映射
grep -rn "router.|app." src/ --include=".ts" |
grep -oE ".(get|post|put|delete|patch)(['"][^'"]+['"]" |
sed "s/.(.)('(.*)'/\U\1 \2/"
grep -oE ".(get|post|put|delete|patch)(['"][^'"]+['"]" |
sed "s/.(.)('(.*)'/\U\1 \2/"
undefinedgrep -rn "router.|app." src/ --include=".ts" |
grep -oE ".(get|post|put|delete|patch)(['"][^'"]+['"]" |
sed "s/.(.)('(.*)'/\U\1 \2/"
grep -oE ".(get|post|put|delete|patch)(['"][^'"]+['"]" |
sed "s/.(.)('(.*)'/\U\1 \2/"
undefinedFastAPI
FastAPI
bash
undefinedbash
undefinedFind all route decorators
查找所有路由装饰器
grep -rn "@app.|@router." . --include="*.py" |
grep -E "@(app|router).(get|post|put|delete|patch)"
grep -E "@(app|router).(get|post|put|delete|patch)"
grep -rn "@app.|@router." . --include="*.py" |
grep -E "@(app|router).(get|post|put|delete|patch)"
grep -E "@(app|router).(get|post|put|delete|patch)"
Extract with path and function name
提取路径和函数名
grep -rn "@(app|router).(get|post|put|delete|patch)" . --include=".py" |
grep -oE "@(app|router).(get|post|put|delete|patch)(['"][^'"]['"]"
grep -oE "@(app|router).(get|post|put|delete|patch)(['"][^'"]['"]"
undefinedgrep -rn "@(app|router).(get|post|put|delete|patch)" . --include=".py" |
grep -oE "@(app|router).(get|post|put|delete|patch)(['"][^'"]['"]"
grep -oE "@(app|router).(get|post|put|delete|patch)(['"][^'"]['"]"
undefinedDjango REST Framework
Django REST Framework
bash
undefinedbash
undefinedurlpatterns extraction
提取urlpatterns
grep -rn "path|re_path|url(" . --include="*.py" | grep "urlpatterns" -A 50 |
grep -E "path(['"]" | grep -oE "['"][^'"]+['"]" | head -40
grep -E "path(['"]" | grep -oE "['"][^'"]+['"]" | head -40
grep -rn "path|re_path|url(" . --include="*.py" | grep "urlpatterns" -A 50 |
grep -E "path(['"]" | grep -oE "['"][^'"]+['"]" | head -40
grep -E "path(['"]" | grep -oE "['"][^'"]+['"]" | head -40
ViewSet router registration
ViewSet路由注册
grep -rn "router.register|DefaultRouter|SimpleRouter" . --include="*.py"
---grep -rn "router.register|DefaultRouter|SimpleRouter" . --include="*.py"
---Test Generation Patterns
测试生成模式
Auth Test Matrix
认证测试矩阵
For every authenticated endpoint, generate:
| Test Case | Expected Status |
|---|---|
| No Authorization header | 401 |
| Invalid token format | 401 |
| Valid token, wrong user role | 403 |
| Expired JWT token | 401 |
| Valid token, correct role | 2xx |
| Token from deleted user | 401 |
针对每个需要认证的端点,生成以下测试:
| 测试用例 | 预期状态码 |
|---|---|
| 无Authorization头 | 401 |
| 无效令牌格式 | 401 |
| 有效令牌,但用户角色错误 | 403 |
| 过期JWT令牌 | 401 |
| 有效令牌,角色正确 | 2xx |
| 已删除用户的令牌 | 401 |
Input Validation Matrix
输入验证矩阵
For every POST/PUT/PATCH endpoint with a request body:
| Test Case | Expected Status |
|---|---|
Empty body | 400 or 422 |
| Missing required fields (one at a time) | 400 or 422 |
| Wrong type (string where int expected) | 400 or 422 |
| Boundary: value at min-1 | 400 or 422 |
| Boundary: value at min | 2xx |
| Boundary: value at max | 2xx |
| Boundary: value at max+1 | 400 or 422 |
| SQL injection in string field | 400 or 200 (sanitized) |
| XSS payload in string field | 400 or 200 (sanitized) |
| Null values for required fields | 400 or 422 |
针对每个带请求体的POST/PUT/PATCH端点:
| 测试用例 | 预期状态码 |
|---|---|
空请求体 | 400 或 422 |
| 缺失必填字段(逐个测试) | 400 或 422 |
| 类型错误(预期整数传入字符串) | 400 或 422 |
| 边界值:最小值-1 | 400 或 422 |
| 边界值:最小值 | 2xx |
| 边界值:最大值 | 2xx |
| 边界值:最大值+1 | 400 或 422 |
| 字符串字段中注入SQL语句 | 400 或 200(已 sanitize) |
| 字符串字段中传入XSS载荷 | 400 或 200(已 sanitize) |
| 必填字段传入Null值 | 400 或 422 |
Example Test Files
示例测试文件
→ See references/example-test-files.md for details
→ 详情请查看 references/example-test-files.md
Generating Tests from Route Scan
从路由扫描生成测试
When given a codebase, follow this process:
- Scan routes using the detection commands above
- Read each route handler to understand:
- Expected request body schema
- Auth requirements (middleware, decorators)
- Return types and status codes
- Business rules (ownership, role checks)
- Generate test file per route group using the patterns above
- Name tests descriptively: not
"returns 401 when token is expired""auth test 3" - Use factories/fixtures for test data — never hardcode IDs
- Assert response shape, not just status code
给定代码库时,遵循以下流程:
- 扫描路由 — 使用上述检测命令
- 读取每个路由处理器,了解:
- 预期请求体 schema
- 认证要求(中间件、装饰器)
- 返回类型和状态码
- 业务规则(归属、角色校验)
- 按路由组生成测试文件 — 遵循上述模式
- 测试命名要清晰:使用而非
"令牌过期时返回401""auth test 3" - 使用工厂/夹具生成测试数据 — 绝不硬编码ID
- 断言响应结构 — 不只是断言状态码
Common Pitfalls
常见陷阱
- Testing only happy paths — 80% of bugs live in error paths; test those first
- Hardcoded test data IDs — use factories/fixtures; IDs change between environments
- Shared state between tests — always clean up in afterEach/afterAll
- Testing implementation, not behavior — test what the API returns, not how it does it
- Missing boundary tests — off-by-one errors are extremely common in pagination and limits
- Not testing token expiry — expired tokens behave differently from invalid ones
- Ignoring Content-Type — test that API rejects wrong content types (xml when json expected)
- 仅测试正常路径 — 80%的bug出现在错误路径;优先测试这些场景
- 硬编码测试数据ID — 使用工厂/夹具;ID在不同环境中会变化
- 测试间共享状态 — 务必在afterEach/afterAll中清理
- 测试实现而非行为 — 测试API返回结果,而非内部实现逻辑
- 缺失边界测试 — 分页和限制中极易出现差一错误
- 未测试令牌过期 — 过期令牌与无效令牌行为不同
- 忽略Content-Type — 测试API是否拒绝错误的内容类型(如预期JSON却传入XML)
Best Practices
最佳实践
- One describe block per endpoint — keeps failures isolated and readable
- Seed minimal data — don't load the entire DB; create only what the test needs
- Use for shared setup,
beforeAllfor cleanup — notafterAllfor expensive opsbeforeEach - Assert specific error messages/fields, not just status codes
- Test that sensitive fields (password, secret) are never in responses
- For auth tests, always test the "missing header" case separately from "invalid token"
- Add rate limit tests last — they can interfere with other test suites if run in parallel
- 每个端点对应一个describe块 — 隔离失败场景,提升可读性
- 生成最小化测试数据 — 不要加载整个数据库;仅创建测试所需数据
- 使用做共享初始化,
beforeAll做清理 — 昂贵操作不要用afterAllbeforeEach - 断言具体错误信息/字段,而非仅状态码
- 测试敏感字段(密码、密钥)绝不会出现在响应中
- 认证测试中,务必将"缺失请求头"与"无效令牌"场景分开测试
- 最后添加速率限制测试 — 并行运行时可能干扰其他测试套件