# 设计文档:修复失败的测试 ## Context 当前项目的测试套件包含 316 个测试,其中 7 个失败,1 个错误。主要问题分为四类: 1. **API 不匹配问题**:测试假设 `render_slide` 返回字典列表,但实际实现返回元素对象列表(dataclass 实例) 2. **python-pptx 枚举问题**:`MSO_SHAPE.TEXT_BOX` 在当前 python-pptx 版本中不存在,导致元素类型检测失败 3. **Windows 路径问题**:字符串路径与 Path 对象混合比较导致断言失败 4. **Fixture 缺失**:`mock_template_class` fixture 未定义 项目约束: - 必须保持 100% 测试通过率 - 修复不能破坏现有功能 - 需要保持代码覆盖率 >= 94% ## Goals / Non-Goals **Goals:** - 修复所有 7 个失败测试和 1 个错误测试 - 确保修复后测试仍能有效验证功能正确性 - 改进测试辅助函数的兼容性 **Non-Goals:** - 不修改生产代码的功能逻辑 - 不添加新功能 - 不降低代码覆盖率 ## Decisions ### D1: 处理 API 不匹配(render_slide 返回值) **选项 A**: 修改 `render_slide` 方法,返回字典而非对象 - 优点:保持测试代码不变 - 缺点:需要修改 `pptx_renderer.py` 和 `html_renderer.py` 的调用方式 **选项 B**: 修改测试代码,使用对象属性访问 - 优点:保持生产代码不变,测试更符合实际使用场景 - 缺点:需要修改多个测试文件 **选择:B** - 修改测试代码,因为元素对象提供了更好的类型安全和 IDE 支持 ### D2: 处理 MSO_SHAPE.TEXT_BOX 枚举不存在 **选项 A**: 使用 `shape.has_text_frame` 属性检测文本框 - 优点:跨版本兼容 - 缺点:需要改变检测逻辑 **选项 B**: 检查 `shape.shape_type` 是否等于 `MSO_SHAPE.AUTO_SHAPE_TYPE` (枚举值 1) - 优点:简单直接 - 缺点:可能不准确 **选项 C**: 改用 `isinstance(shape, pptx.shapes.text_frame.TextFrameProxy)` 或类似方法 - 优点:准确 - 缺点:需要了解内部实现 **选择:A** - 使用 `has_text_frame` 属性,这是检测形状是否有文本框的标准方法 ### D3: 处理 Windows 路径比较 **选项 A**: 在测试中使用 `str()` 转换 Path 对象 - 优点:简单 - 缺点:可能引入平台特定代码 **选项 B**: 在 `Presentation` 类中标准化路径存储 - 优点:一劳永逸 - 缺点:影响较大 **选择:A** - 在测试中转换类型,因为这是测试代码问题,不是生产代码问题 ### D4: 处理缺失的 Fixture **选项 A**: 添加 `mock_template_class` fixture - 优点:保持测试完整 - 缺点:需要了解 mock 的使用方式 **选项 B**: 删除该测试(如果功能已被其他测试覆盖) - 优点:减少维护负担 - 缺点:可能降低覆盖度 **选择:A** - 添加 fixture,因为该测试验证的功能未被其他测试覆盖 ## Risks / Trade-offs | 风险 | 描述 | 缓解措施 | |------|------|----------| | 修复后功能回归 | 修改测试可能隐藏真正的 bug | 修复后运行完整测试套件,确认所有测试通过 | | 版本兼容性 | 不同 python-pptx 版本可能有不同行为 | 使用跨版本兼容的 API(如 `has_text_frame`) | | 测试脆弱性 | 测试与实现耦合过紧 | 使用公共 API,减少内部实现细节依赖 | ## Migration Plan 1. 备份当前测试代码 2. 修改 `tests/conftest_pptx.py` 中的 `count_elements_by_type` 方法 3. 修改 `tests/integration/test_presentation.py` 中的测试 4. 修改 `tests/integration/test_rendering_flow.py` 中的测试 5. 修改 `tests/unit/test_presentation.py` 中的测试 6. 添加缺失的 fixture 7. 运行完整测试套件验证修复 8. 确保代码覆盖率不下降 ## Open Questions **Q1**: 是否需要为元素类型检测添加版本兼容性检查? - 当前选择使用 `has_text_frame` 属性,兼容性较好 **Q2**: 是否应该将测试辅助函数移至独立的工具模块? - 当前保持现状,避免引入不必要的重构