# 批量对话配音生成 - 测试文档 **日期**: 2026-02-13 **功能**: 批量对话配音生成接口 **端点**: `POST /api/v1/ai/generate-dialogue-voiceovers` --- ## 📋 测试文件清单 | 文件 | 类型 | 状态 | 说明 | |------|------|------|------| | `tests/unit/services/test_ai_service_dialogue_voiceovers.py` | 单元测试 | ✅ 已创建 | AIService 业务逻辑测试 | | `tests/integration/test_ai_api.py` | 集成测试 | ✅ 已更新 | API 端点集成测试 | | `tests/manual/manual_test_dialogue_voiceovers.py` | 手动测试 | ✅ 已创建 | 交互式手动测试脚本 | --- ## 🧪 单元测试 **文件**: `tests/unit/services/test_ai_service_dialogue_voiceovers.py` ### 测试用例 | 测试用例 | 描述 | 验证点 | |----------|------|--------| | `test_empty_dialogue_ids` | 空对话列表 | ValidationError("对话 ID 列表不能为空") | | `test_exceed_dialogue_limit` | 超过50个对话 | ValidationError("单次最多支持 50 个对话") | | `test_invalid_dialogue_id_format` | 无效 UUID 格式 | ValidationError("无效的对话 ID") | | `test_dialogue_not_found` | 对话不存在 | ValidationError("对话不存在") | | `test_dialogues_from_different_storyboards` | 不同分镜 | ValidationError("必须属于同一个分镜") | | `test_no_storyboard_permission` | 无分镜权限 | ValidationError("分镜不存在或无权限访问") | | `test_insufficient_credits` | 积分不足 | ValidationError("积分不足") | | `test_create_job_success` | 成功创建任务 | 返回 job_id, task_id, dialogue_count | | `test_parameter_validation` | 参数验证 | 各种边界条件 | ### 运行单元测试 ```bash # 在 Docker 容器内运行 docker exec jointo-server-app pytest tests/unit/services/test_ai_service_dialogue_voiceovers.py -v # 运行特定测试 docker exec jointo-server-app pytest tests/unit/services/test_ai_service_dialogue_voiceovers.py::TestGenerateDialogueVoiceovers::test_create_job_success -v ``` **注意**: 单元测试需要大量 Mock,可能需要调整超时时间。 --- ## 🌐 集成测试 **文件**: `tests/integration/test_ai_api.py` ### 测试用例 | 测试用例 | 描述 | 验证点 | |----------|------|--------| | `test_generate_dialogue_voiceovers_success` | 成功创建任务 | 200 状态码, jobId, dialogueCount | | `test_generate_dialogue_voiceovers_empty_list` | 空列表验证 | 422 状态码 (Pydantic 验证) | | `test_generate_dialogue_voiceovers_exceed_limit` | 数量超限 | 422 状态码 | | `test_generate_dialogue_voiceovers_invalid_speed` | 无效语速 | 422 状态码 | | `test_generate_dialogue_voiceovers_insufficient_credits` | 积分不足 | 400 状态码, 错误消息 | | `test_generate_dialogue_voiceovers_unauthorized` | 未认证 | 401 状态码 | ### 运行集成测试 ```bash # 运行批量对话配音测试 docker exec jointo-server-app pytest tests/integration/test_ai_api.py::TestGenerateDialogueVoiceoversAPI -v # 运行所有 AI API 测试 docker exec jointo-server-app pytest tests/integration/test_ai_api.py -v ``` **已知问题**: 当前测试框架的 `async_client` fixture 有版本兼容性问题,需要更新 httpx 版本或修复 fixture。 --- ## 🖐️ 手动测试 **文件**: `tests/manual/manual_test_dialogue_voiceovers.py` ### 使用方法 ```bash # 1. 设置环境变量(用户 Token) export TEST_TOKEN="your-jwt-token-here" # 2. 运行脚本 cd server/tests/manual python manual_test_dialogue_voiceovers.py ``` ### 测试模式 #### 模式 1:完整功能测试 1. 输入分镜 ID 2. 自动创建 3 个测试对话 3. 批量生成配音 4. 轮询任务状态(最多 60 秒) 5. 显示成功/失败统计 #### 模式 2:参数验证测试 - 空对话列表 → 422 - 对话数量超限(51个)→ 422 - 无效语速(5.0)→ 422 - 无效音量(3.0)→ 422 #### 模式 3:全部执行 先执行参数验证测试,再执行完整功能测试。 ### 示例输出 ``` ============================================================ 批量对话配音生成 - 手动测试 ============================================================ 请输入分镜 ID(或按回车跳过创建对话): 550e8400-e29b-41d4-a716-446655440000 📝 创建测试对话... ✅ 对话 1 创建成功: d1d2d3d4-1234-5678-90ab-cdef12345678 ✅ 对话 2 创建成功: e2e3e4e5-1234-5678-90ab-cdef12345679 ✅ 对话 3 创建成功: f3f4f5f6-1234-5678-90ab-cdef12345680 🎙️ 批量生成配音(共 3 个对话)... 📤 请求参数: { "dialogue_ids": [ "d1d2d3d4-1234-5678-90ab-cdef12345678", "e2e3e4e5-1234-5678-90ab-cdef12345679", "f3f4f5f6-1234-5678-90ab-cdef12345680" ], "voice_id": "EXAVITQu4vr4xnSDxMaL", "voice_name": "Bella", "speed": 1.0, "volume": 1.0, "pitch": 1.0, "is_active": true } 📥 响应状态码: 200 📥 响应数据: { "code": 200, "message": "批量配音生成任务创建成功", "data": { "jobId": "j1j2j3j4-1234-5678-90ab-cdef12345680", "taskId": "celery-task-id-123", "status": "pending", "estimatedCredits": 60, "dialogueCount": 3 } } ✅ 任务创建成功! Job ID: j1j2j3j4-1234-5678-90ab-cdef12345680 对话数量: 3 预计积分: 60 🔄 开始轮询任务状态... [1/30] 状态: PENDING, 进度: 0% [2/30] 状态: PROCESSING, 进度: 10% [3/30] 状态: PROCESSING, 进度: 35% [4/30] 状态: PROCESSING, 进度: 60% [5/30] 状态: PROCESSING, 进度: 85% [6/30] 状态: COMPLETED, 进度: 100% 🎉 任务完成! 📊 结果统计: 成功: 3 失败: 0 ✅ 成功的配音: - 对话 ID: d1d2d3d4-1234-5678-90ab-cdef12345678 配音 ID: v1v2v3v4-1234-5678-90ab-cdef12345678 音频 URL: https://minio.example.com/ai-generated/dialogue-voiceovers/dialogue_voice_d1d2d3d4.mp3 - 对话 ID: e2e3e4e5-1234-5678-90ab-cdef12345679 配音 ID: v2v3v4v5-1234-5678-90ab-cdef12345679 音频 URL: https://minio.example.com/ai-generated/dialogue-voiceovers/dialogue_voice_e2e3e4e5.mp3 - 对话 ID: f3f4f5f6-1234-5678-90ab-cdef12345680 配音 ID: v3v4v5v6-1234-5678-90ab-cdef12345680 音频 URL: https://minio.example.com/ai-generated/dialogue-voiceovers/dialogue_voice_f3f4f5f6.mp3 ``` --- ## 🔧 使用 cURL 测试 ### 1. 批量生成配音 ```bash export TOKEN="your-jwt-token" export DIALOGUE_ID_1="d1d2d3d4-1234-5678-90ab-cdef12345678" export DIALOGUE_ID_2="e2e3e4e5-1234-5678-90ab-cdef12345679" curl -X POST "http://localhost:6160/api/v1/ai/generate-dialogue-voiceovers" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"dialogue_ids\": [\"$DIALOGUE_ID_1\", \"$DIALOGUE_ID_2\"], \"voice_id\": \"EXAVITQu4vr4xnSDxMaL\", \"voice_name\": \"Bella\", \"speed\": 1.0, \"volume\": 1.0, \"pitch\": 1.0, \"is_active\": true }" | jq ``` ### 2. 查询任务状态 ```bash export JOB_ID="returned-job-id" curl -X GET "http://localhost:6160/api/v1/ai/jobs/$JOB_ID" \ -H "Authorization: Bearer $TOKEN" | jq ``` ### 3. 查看配音结果 ```bash curl -X GET "http://localhost:6160/api/v1/storyboard-resources/dialogues/$DIALOGUE_ID_1/voiceovers" \ -H "Authorization: Bearer $TOKEN" | jq ``` --- ## ✅ 测试检查清单 ### 基本功能 - [ ] 成功创建批量配音任务 - [ ] 配音写入 `storyboard_voiceovers` 表 - [ ] 任务状态正确更新(PENDING → PROCESSING → COMPLETED) - [ ] 进度正确更新(0% → 100%) ### 参数验证 - [ ] 空对话列表 → 422 - [ ] 超过 50 个对话 → 422 - [ ] 无效对话 ID → 400 - [ ] 对话属于不同分镜 → 400 - [ ] 无效语速(< 0.25 或 > 4.0)→ 422 - [ ] 无效音量(< 0.0 或 > 2.0)→ 422 - [ ] 无效音调(< 0.5 或 > 2.0)→ 422 ### 权限验证 - [ ] 用户不存在 → 400 - [ ] 对话不存在 → 400 - [ ] 分镜不存在 → 400 - [ ] 无分镜权限 → 403 ### 积分系统 - [ ] 积分不足 → 400 - [ ] 积分正确预扣 - [ ] 任务成功后积分确认 - [ ] 部分失败不退款 ### 部分失败容错 - [ ] 单个对话失败,其他继续 - [ ] 成功的配音保留在数据库 - [ ] 失败原因在 `outputData.failed_dialogues` 中记录 ### 激活配音 - [ ] `is_active=true` 自动停用其他配音 - [ ] `is_active=false` 不影响现有激活状态 ### 性能测试 - [ ] 10 个对话的生成时间 < 60 秒 - [ ] 50 个对话的生成时间 < 300 秒 - [ ] 并发 5 个请求不崩溃 --- ## 🐛 已知问题 ### 1. 集成测试 Fixture 问题 **问题**: `async_client` fixture 报错 `TypeError: AsyncClient.__init__() got an unexpected keyword argument 'app'` **原因**: httpx 版本与测试框架不兼容 **解决方案**: - 升级 httpx 到最新版本 - 或修改 `tests/conftest.py` 中的 fixture 实现 ### 2. 单元测试超时 **问题**: 单元测试运行时间过长 **原因**: 数据库 fixture 初始化耗时 **解决方案**: - 使用更轻量的 Mock - 减少数据库操作 - 增加超时时间 --- ## 📝 后续优化 ### 测试覆盖率 - [ ] 增加边界条件测试 - [ ] 增加并发测试 - [ ] 增加性能压测 - [ ] 增加错误恢复测试 ### 测试自动化 - [ ] 集成到 CI/CD 流程 - [ ] 自动生成测试报告 - [ ] 代码覆盖率监控 ### 文档完善 - [ ] 添加更多使用示例 - [ ] 录制测试视频 - [ ] 编写故障排查指南 --- ## 🎯 建议执行顺序 1. **立即执行**:手动测试脚本(验证核心功能) 2. **修复 Fixture**:解决集成测试的 httpx 问题 3. **补充测试**:增加更多边界条件测试 4. **性能测试**:验证批量处理性能 5. **集成 CI/CD**:自动化测试流程 --- ## 📞 联系方式 如有问题,请查阅: - RFC 145: `/docs/server/rfcs/145-dialogue-voiceovers-batch-generation.md` - Changelog: `/docs/server/changelogs/2026-02-13-dialogue-voiceovers-batch-generation.md` - 实施总结: `/docs/server/IMPLEMENTATION-SUMMARY-dialogue-voiceovers.md`