Files
effekt-interface/api_test_document.md
2026-05-07 19:21:19 +08:00

416 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# API 测试文档
## 1. 接口概览
本项目基于 Flask 框架实现,提供了完整的测试平台 API包括项目管理、用例管理、计划执行、报告生成、权限管理等功能。
### 基础信息
- 基础 URL: `http://localhost:8081/it/api`
- 认证方式: `accessToken` 头部
- 响应格式: JSON
## 2. 模块分类
| 模块 | 前缀 | 主要功能 |
|------|------|----------|
| SQL 项目 | `/` | SQL 项目管理 |
| 项目管理 | `/project` | 项目 CRUD、环境管理 |
| 项目成员 | `/project/member` | 项目成员管理 |
| 产品管理 | `/product` | 产品 CRUD |
| 模块管理 | `/module` | 测试模块管理 |
| 用例管理 | `/case` | 测试用例 CRUD、快照、评审 |
| 计划管理 | `/plan` | 测试计划、轮次、执行 |
| 报告管理 | `/report` | 测试报告生成与查询 |
| Bug 管理 | `/bug` | Bug 追踪与管理 |
| 造数器 | `/data` | 数据构建与任务管理 |
| 权限管理 | `/role`, `/permission`, `/menu` | 角色、权限、菜单管理 |
| 用户管理 | `/user` | 用户 CRUD、角色分配 |
| 认证 | `/auth` | 登录、注册 |
## 3. 详细接口测试文档
### 3.1 SQL 项目模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/list` | GET | `sql_project:list` | 查询 SQL 项目列表 | pageNo, pageSize | `{"code": 20000, "data": {...}}` |
| `/create` | POST | `sql_project:create` | 创建 SQL 项目 | 详见控制器 | `{"code": 20000, "data": {"sqlId": 1}}` |
| `/detail` | GET | `sql_project:detail` | 查询 SQL 项目详情 | id | `{"code": 20000, "data": {...}}` |
| `/delete` | POST | `sql_project:delete` | 删除 SQL 项目 | id | `{"code": 20000, "data": {"sqlId": 1}}` |
| `/execute` | POST | `sql_project:execute` | 执行 SQL 项目 | id, envId | `{"code": 20000, "data": {...}}` |
**测试用例:**
1. 正常查询:`GET /list?pageNo=1&pageSize=10`
2. 成功创建:`POST /create` 传入完整参数
3. 详情查询:`GET /detail?id=1`
4. 成功删除:`POST /delete` 传入 id
5. 执行 SQL`POST /execute` 传入 id 和环境
### 3.2 项目管理模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/project/list` | GET | `project:list` | 查询项目列表 | pageNo, pageSize, productId | `{"code": 20000, "data": {"list": [...], "total": 10}}` |
| `/project/detail` | GET | `project:detail` | 查询项目详情 | id | `{"code": 20000, "data": {...}}` |
| `/project/create` | POST | `project:create` | 创建项目 | name, productId, desc | `{"code": 20000, "data": {"id": 1}}` |
| `/project/update` | POST | `project:update` | 更新项目 | id, name, desc | `{"code": 20000, "data": {"id": 1}}` |
| `/project/delete` | POST | `project:delete` | 删除项目 | id | `{"code": 20000, "data": {"id": 1}}` |
**测试用例:**
1. 列表查询:`GET /project/list?pageNo=1&pageSize=20`
2. 详情查询:`GET /project/detail?id=1`
3. 创建项目:`POST /project/create` 传入 name, productId
4. 更新项目:`POST /project/update` 传入 id, name
5. 删除项目:`POST /project/delete` 传入 id
### 3.3 环境管理模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/environment/list` | GET | `environment:list` | 查询环境列表 | pageNo, pageSize, projectId | `{"code": 20000, "data": {"list": [...], "total": 5}}` |
| `/environment/create` | POST | `environment:create` | 创建环境 | projectId, name, url, config | `{"code": 20000, "data": {"id": 1}}` |
| `/environment/update` | POST | `environment:update` | 更新环境 | id, name, url, config | `{"code": 20000, "data": {"id": 1}}` |
| `/environment/delete` | POST | `environment:delete` | 删除环境 | id | `{"code": 20000, "data": {"id": 1}}` |
**测试用例:**
1. 环境列表:`GET /environment/list?projectId=1`
2. 创建环境:`POST /environment/create` 传入完整参数
3. 更新环境:`POST /environment/update` 传入 id 和更新字段
4. 删除环境:`POST /environment/delete` 传入 id
### 3.4 项目成员模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/project/member/list` | GET | `project_member:list` | 查询项目成员列表 | project_id, pageNo, pageSize | `{"code": 20000, "data": {"list": [...], "total": 3}}` |
| `/project/member/create` | POST | `project_member:create` | 批量添加项目成员 | project_id, user_ids | `{"code": 20000, "data": {"id": [1, 2, 3]}}` |
**测试用例:**
1. 成员列表:`GET /project/member/list?project_id=1&pageNo=1&pageSize=10`
2. 批量添加:`POST /project/member/create` 传入 `{"project_id": 1, "user_ids": [2, 3]}`
3. 边界测试user_ids 为空数组
4. 错误测试user_ids 不是数组
**响应示例:**
```json
{
"code": 20000,
"data": {
"list": [
{
"id": 1,
"project_id": 1,
"user_id": 2,
"role": 1,
"role_name": "测试经理",
"project_name": "示例项目",
"username": "zhangsan",
"real_name": "张三",
"joined_time": "2026-04-22T10:00:00"
}
],
"total": 1
}
}
```
### 3.5 产品管理模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/product/list` | GET | `product:list` | 查询产品列表 | pageNo, pageSize | `{"code": 20000, "data": {"list": [...], "total": 5}}` |
| `/product/detail` | GET | `product:detail` | 查询产品详情 | id | `{"code": 20000, "data": {...}}` |
| `/product/create` | POST | `product:create` | 创建产品 | name, desc | `{"code": 20000, "data": {"id": 1}}` |
| `/product/update` | POST | `product:update` | 更新产品 | id, name, desc | `{"code": 20000, "data": {"id": 1}}` |
| `/product/delete` | POST | `product:delete` | 删除产品 | id | `{"code": 20000, "data": {"id": 1}}` |
**测试用例:**
1. 产品列表:`GET /product/list?pageNo=1&pageSize=20`
2. 详情查询:`GET /product/detail?id=1`
3. 创建产品:`POST /product/create` 传入 name
4. 更新产品:`POST /product/update` 传入 id, name
5. 删除产品:`POST /product/delete` 传入 id
### 3.6 模块管理模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/module/tree` | GET | `module:list` | 获取模块树 | projectId | `{"code": 20000, "data": [...]}` |
| `/module/create` | POST | `module:create` | 创建模块 | projectId, name, parentId | `{"code": 20000, "data": {"id": 1}}` |
| `/module/update` | POST | `module:update` | 更新模块 | id, name | `{"code": 20000, "data": {"id": 1}}` |
| `/module/delete` | POST | `module:delete` | 删除模块 | id | `{"code": 20000, "data": {"id": 1}}` |
**测试用例:**
1. 模块树:`GET /module/tree?projectId=1`
2. 创建模块:`POST /module/create` 传入 projectId, name
3. 更新模块:`POST /module/update` 传入 id, name
4. 删除模块:`POST /module/delete` 传入 id
### 3.7 用例管理模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/case/list` | GET | `case:list` | 查询用例列表 | moduleId, pageNo, pageSize | `{"code": 20000, "data": {"list": [...], "total": 20}}` |
| `/case/detail` | GET | `case:detail` | 查询用例详情 | id | `{"code": 20000, "data": {...}}` |
| `/case/create` | POST | `case:create` | 创建用例 | moduleId, title, steps | `{"code": 20000, "data": {"id": 1}}` |
| `/case/update` | POST | `case:update` | 更新用例 | id, title, steps | `{"code": 20000, "data": {"id": 1}}` |
| `/case/delete` | POST | `case:delete` | 删除用例 | id | `{"code": 20000, "data": {"id": 1}}` |
| `/case/snapshot/create` | POST | `case_snapshot:create` | 创建用例快照 | caseId, reason | `{"code": 20000, "data": {"id": 1}}` |
| `/case/snapshot/list` | GET | `case_snapshot:list` | 查询用例快照 | caseId | `{"code": 20000, "data": [...]}` |
| `/case/review/create` | POST | `case_review:create` | 创建用例评审 | caseId, reviewerId | `{"code": 20000, "data": {"id": 1}}` |
| `/case/review/update` | POST | `case_review:update` | 更新评审状态 | id, status | `{"code": 20000, "data": {"id": 1}}` |
| `/case/review/list` | GET | `case_review:list` | 查询评审列表 | projectId | `{"code": 20000, "data": [...]}` |
**测试用例:**
1. 用例列表:`GET /case/list?moduleId=1&pageNo=1&pageSize=10`
2. 详情查询:`GET /case/detail?id=1`
3. 创建用例:`POST /case/create` 传入完整参数
4. 更新用例:`POST /case/update` 传入 id, title, steps
5. 删除用例:`POST /case/delete` 传入 id
6. 创建快照:`POST /case/snapshot/create` 传入 caseId
7. 快照列表:`GET /case/snapshot/list?caseId=1`
8. 创建评审:`POST /case/review/create` 传入 caseId, reviewerId
9. 更新评审:`POST /case/review/update` 传入 id, status
10. 评审列表:`GET /case/review/list?projectId=1`
### 3.8 计划管理模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/plan/list` | GET | `plan:list` | 查询计划列表 | projectId, pageNo, pageSize | `{"code": 20000, "data": {"list": [...], "total": 5}}` |
| `/plan/detail` | GET | `plan:detail` | 查询计划详情 | id | `{"code": 20000, "data": {...}}` |
| `/plan/create` | POST | `plan:create` | 创建计划 | projectId, name, startDate, endDate | `{"code": 20000, "data": {"id": 1}}` |
| `/plan/update` | POST | `plan:update` | 更新计划 | id, name, startDate, endDate | `{"code": 20000, "data": {"id": 1}}` |
| `/plan/delete` | POST | `plan:delete` | 删除计划 | id | `{"code": 20000, "data": {"id": 1}}` |
| `/plan/round/create` | POST | `plan_round:create` | 创建轮次 | planId, name | `{"code": 20000, "data": {"id": 1}}` |
| `/plan/round/list` | GET | `plan_round:list` | 查询轮次列表 | planId | `{"code": 20000, "data": [...]}` |
| `/plan/case/add` | POST | `plan_case:add` | 添加用例到计划 | planId, caseIds | `{"code": 20000, "data": {"addedCount": 5}}` |
| `/plan/case/list` | GET | `plan_case:list` | 查询计划用例列表 | planId, roundId | `{"code": 20000, "data": [...]}` |
| `/plan/case/execute` | POST | `plan_case:execute` | 执行计划用例 | id, status, comment | `{"code": 20000, "data": {"id": 1}}` |
| `/plan/progress` | GET | `plan:progress` | 查询计划进度 | planId | `{"code": 20000, "data": {...}}` |
**测试用例:**
1. 计划列表:`GET /plan/list?projectId=1&pageNo=1&pageSize=10`
2. 详情查询:`GET /plan/detail?id=1`
3. 创建计划:`POST /plan/create` 传入完整参数
4. 更新计划:`POST /plan/update` 传入 id, name
5. 删除计划:`POST /plan/delete` 传入 id
6. 创建轮次:`POST /plan/round/create` 传入 planId, name
7. 轮次列表:`GET /plan/round/list?planId=1`
8. 添加用例:`POST /plan/case/add` 传入 planId, caseIds
9. 用例列表:`GET /plan/case/list?planId=1&roundId=1`
10. 执行用例:`POST /plan/case/execute` 传入 id, status
11. 进度查询:`GET /plan/progress?planId=1`
### 3.9 报告管理模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/report/list` | GET | `report:list` | 查询报告列表 | projectId, pageNo, pageSize | `{"code": 20000, "data": {"list": [...], "total": 5}}` |
| `/report/detail` | GET | `report:detail` | 查询报告详情 | id | `{"code": 20000, "data": {...}}` |
| `/report/generate` | POST | `report:generate` | 生成测试报告 | planId, roundId, title | `{"code": 20000, "data": {"id": 1}}` |
**测试用例:**
1. 报告列表:`GET /report/list?projectId=1&pageNo=1&pageSize=10`
2. 详情查询:`GET /report/detail?id=1`
3. 生成报告:`POST /report/generate` 传入 planId, roundId, title
### 3.10 造数器模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/data/builder/list` | GET | `data_builder:list` | 查询造数器列表 | pageNo, pageSize | `{"code": 20000, "data": {"list": [...], "total": 5}}` |
| `/data/builder/detail` | GET | `data_builder:detail` | 查询造数器详情 | id | `{"code": 20000, "data": {...}}` |
| `/data/builder/create` | POST | `data_builder:create` | 创建造数器 | name, config | `{"code": 20000, "data": {"id": 1}}` |
| `/data/builder/update` | POST | `data_builder:update` | 更新造数器 | id, name, config | `{"code": 20000, "data": {"id": 1}}` |
| `/data/builder/delete` | POST | `data_builder:delete` | 删除造数器 | id | `{"code": 20000, "data": {"id": 1}}` |
| `/data/builder/execute` | POST | `data_builder:execute` | 执行造数器 | id, envId | `{"code": 20000, "data": {...}}` |
| `/data/task/status` | GET | `data_task:status` | 查询任务状态 | taskId | `{"code": 20000, "data": {...}}` |
**测试用例:**
1. 造数器列表:`GET /data/builder/list?pageNo=1&pageSize=10`
2. 详情查询:`GET /data/builder/detail?id=1`
3. 创建造数器:`POST /data/builder/create` 传入 name, config
4. 更新造数器:`POST /data/builder/update` 传入 id, name, config
5. 删除造数器:`POST /data/builder/delete` 传入 id
6. 执行造数器:`POST /data/builder/execute` 传入 id, envId
7. 任务状态:`GET /data/task/status?taskId=1`
### 3.11 权限管理模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/role/list` | GET | `role:list` | 查询角色列表 | - | `{"code": 20000, "data": [...]}` |
| `/role/page/list` | GET | `role:list` | 分页查询角色 | pageNo, pageSize | `{"code": 20000, "data": {"list": [...], "total": 5}}` |
| `/role/detail` | GET | `role:detail` | 查询角色详情 | id | `{"code": 20000, "data": {...}}` |
| `/role/create` | POST | `role:create` | 创建角色 | name, status | `{"code": 20000, "data": {"id": 1}}` |
| `/role/update` | POST | `role:update` | 更新角色 | id, name, status | `{"code": 20000, "data": {"id": 1}}` |
| `/role/delete` | POST | `role:delete` | 删除角色 | id | `{"code": 20000, "data": {"id": 1}}` |
| `/permission/list` | GET | `permission:list` | 查询权限列表 | - | `{"code": 20000, "data": [...]}` |
| `/permission/detail` | GET | `permission:detail` | 查询权限详情 | id | `{"code": 20000, "data": {...}}` |
| `/permission/create` | POST | `permission:create` | 创建权限 | name, code | `{"code": 20000, "data": {"id": 1}}` |
| `/permission/update` | POST | `permission:update` | 更新权限 | id, name, code | `{"code": 20000, "data": {"id": 1}}` |
| `/permission/delete` | POST | `permission:delete` | 删除权限 | id | `{"code": 20000, "data": {"id": 1}}` |
| `/menu/tree` | GET | `menu:list` | 获取菜单树 | - | `{"code": 20000, "data": [...]}` |
| `/menu/current/list` | GET | - | 获取当前用户菜单 | - | `{"code": 20000, "data": [...]}` |
| `/role/menu/tree` | GET | `role_menu:list` | 获取角色菜单树 | roleId | `{"code": 20000, "data": [...]}` |
| `/menu/detail` | GET | `menu:detail` | 查询菜单详情 | id | `{"code": 20000, "data": {...}}` |
| `/menu/create` | POST | `menu:create` | 创建菜单 | name, path, parentId | `{"code": 20000, "data": {"id": 1}}` |
| `/menu/update` | POST | `menu:update` | 更新菜单 | id, name, path | `{"code": 20000, "data": {"id": 1}}` |
| `/menu/delete` | POST | `menu:delete` | 删除菜单 | id | `{"code": 20000, "data": {"id": 1}}` |
| `/role/permission/list` | GET | `role_permission:list` | 查询角色权限 | roleId | `{"code": 20000, "data": [...]}` |
| `/role/permission/assign` | POST | `role_permission:assign` | 分配角色权限 | roleId, permissionIds | `{"code": 20000, "data": {"id": 1}}` |
| `/role/menu/list` | GET | `role_menu:list` | 查询角色菜单 | roleId | `{"code": 20000, "data": [...]}` |
| `/role/menu/assign` | POST | `role_menu:assign` | 分配角色菜单 | roleId, menuIds | `{"code": 20000, "data": {"id": 1}}` |
**测试用例:**
1. 角色列表:`GET /role/list`
2. 分页角色:`GET /role/page/list?pageNo=1&pageSize=10`
3. 角色详情:`GET /role/detail?id=1`
4. 创建角色:`POST /role/create` 传入 name, status
5. 分配权限:`POST /role/permission/assign` 传入 roleId, permissionIds
6. 分配菜单:`POST /role/menu/assign` 传入 roleId, menuIds
7. 菜单树:`GET /menu/tree`
8. 当前菜单:`GET /menu/current/list`
### 3.12 用户管理模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/user/list` | GET | `user:list` | 查询用户列表 | pageNo, pageSize | `{"code": 20000, "data": {"list": [...], "total": 10}}` |
| `/user/detail` | GET | `user:detail` | 查询用户详情 | id | `{"code": 20000, "data": {...}}` |
| `/user/create` | POST | `user:create` | 创建用户 | username, real_name, password | `{"code": 20000, "data": {"id": 1}}` |
| `/user/update` | POST | `user:update` | 更新用户 | id, real_name, password | `{"code": 20000, "data": {"id": 1}}` |
| `/user/delete` | POST | `user:delete` | 删除用户 | id | `{"code": 20000, "data": {"id": 1}}` |
| `/user/role/list` | GET | `user_role:list` | 查询用户角色 | userId | `{"code": 20000, "data": [...]}` |
| `/user/role/assign` | POST | `user_role:assign` | 分配用户角色 | userId, roleIds | `{"code": 20000, "data": {"id": 1}}` |
**测试用例:**
1. 用户列表:`GET /user/list?pageNo=1&pageSize=20`
2. 详情查询:`GET /user/detail?id=1`
3. 创建用户:`POST /user/create` 传入 username, real_name, password
4. 更新用户:`POST /user/update` 传入 id, real_name
5. 删除用户:`POST /user/delete` 传入 id
6. 用户角色:`GET /user/role/list?userId=1`
7. 分配角色:`POST /user/role/assign` 传入 userId, roleIds
### 3.14 认证模块
| 接口 | 方法 | 权限 | 描述 | 请求参数 | 响应 |
|------|------|------|------|----------|------|
| `/auth/register` | POST | - | 用户注册 | username, password, real_name | `{"code": 20000, "data": {"id": 1}}` |
| `/auth/login` | POST | - | 用户登录 | username, password | `{"code": 20000, "data": {"token": "...", "user": {...}}}` |
**测试用例:**
1. 用户注册:`POST /auth/register` 传入 username, password, real_name
2. 用户登录:`POST /auth/login` 传入 username, password
3. 登录失败:传入错误的用户名或密码
4. 注册失败:传入已存在的用户名
## 4. 认证与权限
### 4.1 认证方式
所有接口(除了 `/auth/register``/auth/login`)都需要在请求头中携带 `accessToken`
```bash
curl -H "accessToken: your_token" http://localhost:8081/it/api/project/list
```
### 4.2 权限控制
每个接口都有对应的权限标识,例如:
- `project:list` - 查看项目列表权限
- `project:create` - 创建项目权限
- `project:update` - 更新项目权限
- `project:delete` - 删除项目权限
## 5. 响应格式
### 5.1 成功响应
```json
{
"code": 20000,
"data": {...}
}
```
### 5.2 失败响应
```json
{
"code": 40009,
"msg": "错误信息"
}
```
### 5.3 错误码说明
| 错误码 | 描述 |
|--------|------|
| 40004 | 未登录或缺少token |
| 40008 | 数据库连接超时 |
| 40009 | 参数错误或业务逻辑错误 |
| 40011 | 资源不存在或查询失败 |
| 40012 | 更新/删除操作失败 |
## 6. 测试工具与脚本
### 6.1 使用 curl 测试
**获取项目列表:**
```bash
curl 'http://localhost:8081/it/api/project/list?pageNo=1&pageSize=10' \
-H 'accessToken: your_token'
```
**添加项目成员:**
```bash
curl 'http://localhost:8081/it/api/project/member/create' \
-H 'Content-Type: application/json' \
-H 'accessToken: your_token' \
--data-raw '{"project_id": 1, "user_ids": [2, 3]}'
```
### 6.2 使用 Postman 测试
1. 导入本测试文档
2. 设置环境变量 `base_url``http://localhost:8081/it/api`
3. 设置环境变量 `token` 为登录后获取的 accessToken
4. 运行测试集合
## 7. 性能测试建议
1. **并发测试**:使用 JMeter 模拟 50-100 并发用户
2. **响应时间**:目标平均响应时间 < 500ms
3. **吞吐量**:目标 QPS > 100
4. **数据库性能**:监控 SQL 执行时间,优化慢查询
5. **内存使用**:监控服务内存占用,避免内存泄漏
## 8. 安全测试建议
1. **认证绕过**:测试无 token 访问受保护接口
2. **权限越权**:测试低权限用户访问高权限接口
3. **SQL 注入**:测试输入参数中的 SQL 注入攻击
4. **XSS 攻击**:测试输入参数中的 XSS 攻击
5. **CSRF 攻击**:测试跨站请求伪造防护
## 9. 测试环境配置
### 9.1 本地环境
- Python 3.8+
- Flask 2.0+
- MySQL 5.7+
- Redis可选用于缓存
### 9.2 环境变量
- `FLASK_APP`: `app.py`
- `FLASK_ENV`: `development``production`
- `DATABASE_URL`: 数据库连接字符串
- `SECRET_KEY`: 用于 JWT 签名
## 10. 总结
本测试文档涵盖了项目所有 API 接口的测试用例,包括:
- 功能测试:验证接口正常功能
- 边界测试:测试参数边界情况
- 错误测试:测试错误处理
- 性能测试:验证系统性能
- 安全测试:验证系统安全性
通过系统性的测试,可以确保 API 接口的稳定性、可靠性和安全性,为前端应用提供可靠的后端支持。