# 测试辅助函数统一和 API 响应格式修复 **日期**: 2026-02-05 **类型**: 测试架构优化 + Bug 修复 **影响范围**: 集成测试 ## 📋 变更概述 统一了测试辅助函数,消除代码重复;修复了 AI API 测试中的 schema 验证错误。 ## ✅ 任务完成情况 ### 任务 1:统一测试辅助函数 **问题**:7 个集成测试文件中存在重复的 `assert_success()` 和 `safe_json()` 函数定义,导致代码重复和维护困难。 **解决方案**: 1. 在 `tests/conftest.py` 中添加了 4 个全局辅助函数: - `assert_success(data, message)` - 兼容新旧 API 响应格式的成功断言 - `assert_error(data, expected_code, message)` - 兼容新旧格式的错误断言 - `assert_response_format(data, check_timestamp)` - 严格验证新 5 字段 API 响应格式 - `safe_json(response)` - 安全的 JSON 响应解析 2. 从以下 7 个文件中删除了重复定义并更新导入: - `tests/integration/test_project_api.py` - `tests/integration/test_screenplay_tag_api.py` - `tests/integration/test_user_api.py` - `tests/integration/test_ai_conversation_api.py` - `tests/integration/test_screenplay_api.py` - `tests/integration/test_project_resource_api.py` - `tests/integration/test_file_storage_api.py` **结果**:✅ 完成 - 消除了约 140 行重复代码 - 所有测试文件现在使用统一的辅助函数 - 更易于维护和扩展 ### 任务 2:修复 AI API 测试的 Schema 验证错误 **问题**:`tests/integration/test_ai_api.py` 中的 mock 返回值与 API response schema 定义不匹配,导致测试失败。 **具体问题**: 1. Mock 返回值缺少必需字段 `task_id` 2. `status` 字段类型错误(期望字符串,实际返回枚举) 3. 包含多余字段(`job_type`, `created_at`) 4. `AIJobStatusResponse` 缺少必需字段 5. `UsageStatsResponse` 字段名称不匹配(`total_credits` vs `total_credits_used`) 6. 断言中 `code` 字段期望值错误(期望 200,实际为 0) **解决方案**:修复了所有 mock 返回值和断言: #### 修复的测试方法(11 个): 1. `test_generate_image_success` - 添加 `task_id`,修复 status 和 code 2. `test_generate_image_validation_error` - 修复错误响应断言 3. `test_generate_image_insufficient_credits` - 修复错误响应断言 4. `test_generate_image_unauthorized` - 允许 401/403 状态码 5. `test_generate_video_text2video` - 添加 `task_id` 等必需字段 6. `test_generate_video_img2video` - 添加 `task_id` 等必需字段 7. `test_generate_sound_success` - 添加完整 schema 字段 8. `test_generate_voice_success` - 添加完整 schema 字段 9. `test_generate_subtitle_success` - 添加完整 schema 字段 10. `test_process_text_screenplay_parse` - 添加完整 schema 字段 11. `test_get_job_status` - 添加所有必需字段(14 个字段) 12. `test_get_usage_stats` - 修复字段名称和结构 **修复示例**: ```python # 修复前(缺少 task_id) mock_service.generate_image = AsyncMock(return_value={ 'job_id': str(uuid4()), 'status': AIJobStatus.PENDING, # ❌ 枚举类型 'job_type': AIJobType.IMAGE, # ❌ 不应该在响应中 }) # 修复后(完整字段) mock_service.generate_image = AsyncMock(return_value={ 'job_id': str(uuid4()), 'task_id': 'mock-task-id-123', # ✅ 添加 'status': 'pending', # ✅ 字符串类型 'estimated_cost': 0.05, # ✅ 添加 'estimated_credits': 10 # ✅ 添加 }) ``` **结果**:✅ 完成 - 24 个 AI API 测试全部通过 ✅ - 所有 mock 返回值现在与 schema 定义匹配 - 响应格式验证正常工作 ## 📊 测试结果 ### AI API 测试(tests/integration/test_ai_api.py) - **状态**: ✅ 全部通过 - **测试数量**: 24 - **通过**: 24 - **失败**: 0 - **耗时**: 0.51s ### 集成测试总体情况 - **总测试数**: 381 - **已运行**: 48 - **通过**: 47 - **失败**: 1 (test_ai_integration.py, 非本次修复范围) ## 🔧 技术细节 ### API 响应格式规范 #### 新格式(5 字段): ```json { "success": true, "code": 0, // ⚠️ 注意:0 表示成功,不是 200 "message": "Success", "data": {...}, "timestamp": "2026-02-05T09:13:13.267Z" } ``` #### 旧格式(3 字段): ```json { "code": 200, "message": "Success", "data": {...} } ``` ### 重要发现 1. **业务状态码 vs HTTP 状态码**: - `success_response()` 的 `code` 默认值是 `0`(表示业务成功) - HTTP 状态码是 `200`(表示请求成功) - 测试断言应该使用 `data['code'] == 0`,而非 `200` 2. **辅助函数兼容性**: - `assert_success()` 兼容新旧两种格式 - 优先检查 `success` 字段(新格式),回退到 `code` 字段(旧格式) 3. **Schema 验证的重要性**: - FastAPI 的 `response_model` 会严格验证响应数据 - Mock 返回值必须与 schema 定义完全匹配 - 缺少必需字段或类型错误都会导致 `ResponseValidationError` ## 📁 涉及文件 ### 修改的文件(9 个) 1. `server/tests/conftest.py` - 添加全局辅助函数 2. `server/tests/integration/test_project_api.py` - 移除重复定义 3. `server/tests/integration/test_screenplay_tag_api.py` - 移除重复定义 4. `server/tests/integration/test_user_api.py` - 移除重复定义 5. `server/tests/integration/test_ai_conversation_api.py` - 移除重复定义 6. `server/tests/integration/test_screenplay_api.py` - 移除重复定义 7. `server/tests/integration/test_project_resource_api.py` - 移除重复定义 8. `server/tests/integration/test_file_storage_api.py` - 移除重复定义 9. `server/tests/integration/test_ai_api.py` - 修复所有 mock 和断言 ### 创建的脚本(未提交) - `server/scripts/cleanup_test_helpers.py` - 自动化清理脚本(已完成任务) ## 🎯 后续建议 ### 短期优化 1. ✅ 运行完整测试套件验证所有测试 2. ⚠️ 修复 `test_ai_integration.py::TestAIConversations::test_create_conversation` 失败 3. 📝 更新测试文档说明新的辅助函数用法 ### 长期改进 1. 逐步将所有测试迁移到新的 5 字段 API 响应格式 2. 考虑使用 `assert_response_format()` 进行严格的格式验证 3. 为 mock 返回值创建标准工厂函数,避免重复定义 4. 解决事件循环警告(非阻塞,但影响日志清洁度) ## 🔗 相关文档 - [测试规范](../../.claude/skills/jointo-tech-stack/references/testing.md) - [API 设计规范](../../.claude/skills/jointo-tech-stack/references/api-design.md) - [后端开发规范](../../.claude/skills/jointo-tech-stack/references/backend.md) - [测试架构重构](./2026-02-04-test-architecture-refactoring.md) ## 👥 维护者 - **执行者**: Claude (Agent) - **审核者**: 待定 - **日期**: 2026-02-05 --- **最后更新**: 2026-02-05 17:15 CST