You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.8 KiB
6.8 KiB
测试辅助函数统一和 API 响应格式修复
日期: 2026-02-05
类型: 测试架构优化 + Bug 修复
影响范围: 集成测试
📋 变更概述
统一了测试辅助函数,消除代码重复;修复了 AI API 测试中的 schema 验证错误。
✅ 任务完成情况
任务 1:统一测试辅助函数
问题:7 个集成测试文件中存在重复的 assert_success() 和 safe_json() 函数定义,导致代码重复和维护困难。
解决方案:
-
在
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 响应解析
-
从以下 7 个文件中删除了重复定义并更新导入:
tests/integration/test_project_api.pytests/integration/test_screenplay_tag_api.pytests/integration/test_user_api.pytests/integration/test_ai_conversation_api.pytests/integration/test_screenplay_api.pytests/integration/test_project_resource_api.pytests/integration/test_file_storage_api.py
结果:✅ 完成
- 消除了约 140 行重复代码
- 所有测试文件现在使用统一的辅助函数
- 更易于维护和扩展
任务 2:修复 AI API 测试的 Schema 验证错误
问题:tests/integration/test_ai_api.py 中的 mock 返回值与 API response schema 定义不匹配,导致测试失败。
具体问题:
- Mock 返回值缺少必需字段
task_id status字段类型错误(期望字符串,实际返回枚举)- 包含多余字段(
job_type,created_at) AIJobStatusResponse缺少必需字段UsageStatsResponse字段名称不匹配(total_creditsvstotal_credits_used)- 断言中
code字段期望值错误(期望 200,实际为 0)
解决方案:修复了所有 mock 返回值和断言:
修复的测试方法(11 个):
test_generate_image_success- 添加task_id,修复 status 和 codetest_generate_image_validation_error- 修复错误响应断言test_generate_image_insufficient_credits- 修复错误响应断言test_generate_image_unauthorized- 允许 401/403 状态码test_generate_video_text2video- 添加task_id等必需字段test_generate_video_img2video- 添加task_id等必需字段test_generate_sound_success- 添加完整 schema 字段test_generate_voice_success- 添加完整 schema 字段test_generate_subtitle_success- 添加完整 schema 字段test_process_text_screenplay_parse- 添加完整 schema 字段test_get_job_status- 添加所有必需字段(14 个字段)test_get_usage_stats- 修复字段名称和结构
修复示例:
# 修复前(缺少 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 字段):
{
"success": true,
"code": 0, // ⚠️ 注意:0 表示成功,不是 200
"message": "Success",
"data": {...},
"timestamp": "2026-02-05T09:13:13.267Z"
}
旧格式(3 字段):
{
"code": 200,
"message": "Success",
"data": {...}
}
重要发现
-
业务状态码 vs HTTP 状态码:
success_response()的code默认值是0(表示业务成功)- HTTP 状态码是
200(表示请求成功) - 测试断言应该使用
data['code'] == 0,而非200
-
辅助函数兼容性:
assert_success()兼容新旧两种格式- 优先检查
success字段(新格式),回退到code字段(旧格式)
-
Schema 验证的重要性:
- FastAPI 的
response_model会严格验证响应数据 - Mock 返回值必须与 schema 定义完全匹配
- 缺少必需字段或类型错误都会导致
ResponseValidationError
- FastAPI 的
📁 涉及文件
修改的文件(9 个)
server/tests/conftest.py- 添加全局辅助函数server/tests/integration/test_project_api.py- 移除重复定义server/tests/integration/test_screenplay_tag_api.py- 移除重复定义server/tests/integration/test_user_api.py- 移除重复定义server/tests/integration/test_ai_conversation_api.py- 移除重复定义server/tests/integration/test_screenplay_api.py- 移除重复定义server/tests/integration/test_project_resource_api.py- 移除重复定义server/tests/integration/test_file_storage_api.py- 移除重复定义server/tests/integration/test_ai_api.py- 修复所有 mock 和断言
创建的脚本(未提交)
server/scripts/cleanup_test_helpers.py- 自动化清理脚本(已完成任务)
🎯 后续建议
短期优化
- ✅ 运行完整测试套件验证所有测试
- ⚠️ 修复
test_ai_integration.py::TestAIConversations::test_create_conversation失败 - 📝 更新测试文档说明新的辅助函数用法
长期改进
- 逐步将所有测试迁移到新的 5 字段 API 响应格式
- 考虑使用
assert_response_format()进行严格的格式验证 - 为 mock 返回值创建标准工厂函数,避免重复定义
- 解决事件循环警告(非阻塞,但影响日志清洁度)
🔗 相关文档
👥 维护者
- 执行者: Claude (Agent)
- 审核者: 待定
- 日期: 2026-02-05
最后更新: 2026-02-05 17:15 CST