# 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 接口的稳定性、可靠性和安全性,为前端应用提供可靠的后端支持。