# 项目 API 标准化测试验证计划 **测试日期**: 2026-02-11 **测试范围**: `projects.py`, `project_resources.py`, `project_elements.py`, `project_element_tags.py` ## 测试目标 验证 4 个项目相关 API 文件已成功完成标准化改造: 1. ✅ 查询参数支持 camelCase 2. ✅ 响应格式使用 SuccessResponse 3. ✅ 异常处理统一使用 exceptions.py ## 测试清单 ### 1. 异常处理测试 #### 1.1 项目角色 API (`project_elements.py`) **测试场景 1: 创建重复角色名称** ```bash POST /api/v1/projects/{project_id}/characters { "name": "重复角色名", "role_type": "protagonist" } 预期结果: - HTTP 状态码: 400 - 响应体: {"success": false, "code": 400, "message": "该项目下已存在同名角色,请使用其他名称", ...} ``` **测试场景 2: 访问不存在的角色** ```bash GET /api/v1/projects/{project_id}/characters/{non_existent_id} 预期结果: - HTTP 状态码: 404 - 响应体: {"success": false, "code": 404, "message": "角色不存在", ...} ``` #### 1.2 项目场景 API (`project_elements.py`) **测试场景 3: 创建重复场景名称** ```bash POST /api/v1/projects/{project_id}/locations { "name": "重复场景名", "location": "interior" } 预期结果: - HTTP 状态码: 400 - 响应体: {"success": false, "code": 400, "message": "该项目下已存在同名场景,请使用其他名称", ...} ``` #### 1.3 项目道具 API (`project_elements.py`) **测试场景 4: 创建重复道具名称** ```bash POST /api/v1/projects/{project_id}/props { "name": "重复道具名" } 预期结果: - HTTP 状态码: 400 - 响应体: {"success": false, "code": 400, "message": "该项目下已存在同名道具,请使用其他名称", ...} ``` #### 1.4 项目元素标签 API (`project_element_tags.py`) **测试场景 5: 创建标签参数错误** ```bash POST /api/v1/projects/{project_id}/element-tags { "element_type": "invalid_type", "element_id": "invalid_id" } 预期结果: - HTTP 状态码: 400 - 响应体: {"success": false, "code": 400, "message": "...", ...} ``` **测试场景 6: 更新不存在的标签** ```bash PUT /api/v1/projects/{project_id}/element-tags/{non_existent_id} { "tag_label": "新标签名" } 预期结果: - HTTP 状态码: 404 - 响应体: {"success": false, "code": 404, "message": "...", ...} ``` **测试场景 7: 删除不存在的标签** ```bash DELETE /api/v1/projects/{project_id}/element-tags/{non_existent_id} 预期结果: - HTTP 状态码: 404 - 响应体: {"success": false, "code": 404, "message": "...", ...} ``` **测试场景 8: 设置不存在的默认标签** ```bash PUT /api/v1/projects/{project_id}/elements/character/{element_id}/default-tag { "tag_id": "{non_existent_tag_id}" } 预期结果: - HTTP 状态码: 404 - 响应体: {"success": false, "code": 404, "message": "...", ...} ``` ### 2. camelCase 查询参数测试 #### 2.1 项目列表 API (`projects.py`) **测试场景 9: 使用 camelCase 查询参数** ```bash GET /api/v1/projects?folderId={folder_id}&contentType=movie&sortBy=createdAt&sortOrder=desc&pageSize=10 预期结果: - HTTP 状态码: 200 - 响应体包含项目列表 - 分页信息正确 ``` #### 2.2 项目素材 API (`project_resources.py`) **测试场景 10: 使用 camelCase 查询参数** ```bash GET /api/v1/projects/{project_id}/resources?elementTagId={tag_id}&pageSize=20 预期结果: - HTTP 状态码: 200 - 响应体包含素材列表 - 按标签过滤正确 ``` #### 2.3 项目标签 API (`project_element_tags.py`) **测试场景 11: 使用 camelCase 查询参数** ```bash GET /api/v1/projects/{project_id}/element-tags?elementType=character 预期结果: - HTTP 状态码: 200 - 响应体只包含角色类型的标签 ``` ### 3. 响应格式验证 #### 3.1 成功响应格式 **所有成功请求应返回统一格式**: ```json { "success": true, "code": 200, "message": "Success", "data": { ... }, "timestamp": "2026-02-11T10:00:00+00:00" } ``` #### 3.2 错误响应格式 **所有错误请求应返回统一格式**: ```json { "success": false, "code": 400, // 或 404, 403, 500 等 "message": "具体错误消息", "data": null, "timestamp": "2026-02-11T10:00:00+00:00" } ``` ## 自动化测试建议 ### Pytest 测试用例示例 ```python import pytest from httpx import AsyncClient @pytest.mark.asyncio async def test_create_duplicate_character_returns_validation_error( async_client: AsyncClient, auth_headers: dict, project_id: str ): """测试创建重复角色返回 ValidationError (400)""" # 第一次创建 response1 = await async_client.post( f"/api/v1/projects/{project_id}/characters", headers=auth_headers, json={"name": "主角", "role_type": "protagonist"} ) assert response1.status_code == 200 # 第二次创建(重复名称) response2 = await async_client.post( f"/api/v1/projects/{project_id}/characters", headers=auth_headers, json={"name": "主角", "role_type": "protagonist"} ) # 验证返回 ValidationError assert response2.status_code == 400 data = response2.json() assert data["success"] is False assert data["code"] == 400 assert "已存在同名角色" in data["message"] @pytest.mark.asyncio async def test_get_project_tags_with_camelcase_params( async_client: AsyncClient, auth_headers: dict, project_id: str ): """测试查询参数支持 camelCase""" response = await async_client.get( f"/api/v1/projects/{project_id}/element-tags", headers=auth_headers, params={"elementType": "character"} # camelCase 参数 ) assert response.status_code == 200 data = response.json() assert data["success"] is True assert data["code"] == 200 # 验证返回的都是角色标签 for tag in data["data"]: assert tag["element_type"] == "character" ``` ## 回归测试 ### 兼容性验证 1. ✅ 验证 HTTP 状态码未改变 2. ✅ 验证响应格式保持一致 3. ✅ 验证现有前端功能正常运行 ### 性能测试 1. 验证异常处理未引入性能问题 2. 验证查询参数解析性能正常 ## 测试通过标准 - [ ] 所有唯一约束冲突返回 400 ValidationError - [ ] 所有资源不存在返回 404 NotFoundError - [ ] 所有权限不足返回 403 PermissionError - [ ] 所有服务器错误返回 500 InternalServerError - [ ] 查询参数 camelCase 别名正常工作 - [ ] 响应格式符合 SuccessResponse 规范 - [ ] 错误消息清晰易懂 - [ ] 现有功能未受影响 ## 注意事项 1. **不要在生产环境直接测试** - 使用开发或测试环境 2. **保存测试数据** - 某些测试会创建/删除数据 3. **测试顺序** - 先测试创建,再测试更新/删除 4. **清理测试数据** - 测试完成后清理创建的测试数据 ## 测试工具推荐 1. **Postman** - 手动 API 测试 2. **Pytest + httpx** - 自动化测试 3. **curl** - 命令行快速测试 4. **Swagger UI** - 交互式 API 文档测试 (`/docs`)