## Context yaml2pptx 项目目前没有测试代码。项目采用模块化架构,包含以下模块: - core/: 核心领域模型(elements、presentation、template) - loaders/: YAML 加载层 - validators/: 验证层(geometry、resource、result、validator) - renderers/: PPTX 和 HTML 渲染 - preview/: Flask 预览服务器 约束条件: 1. 必须使用 pytest 框架 2. PPTX 文件需要实际生成和验证(Level 2:文件结构、元素数量、内容匹配、位置范围) 3. Preview 测试不启动真实服务器 4. 临时文件使用系统临时目录并自动清理 ## Goals / Non-Goals **Goals:** - 建立全面的测试体系,覆盖单元、集成、端到端三个层级 - 确保核心功能的正确性和稳定性 - 为未来重构提供安全网 - 测试代码结构清晰、易于维护 **Non-Goals:** - 性能测试 - UI/视觉对比测试(像素级) - 100% 代码覆盖率(追求合理覆盖而非完美数字) ## Decisions ### D1: 测试目录结构 采用三层测试结构: ``` tests/ ├── unit/ # 单元测试 - 测试独立函数/类 ├── integration/ # 集成测试 - 测试模块间协作 ├── e2e/ # 端到端测试 - 测试完整用户场景 └── fixtures/ # 测试数据 ``` **理由**:清晰的分层便于理解和维护,符合测试最佳实践。 ### D2: Fixtures 策略 使用 pytest 的 conftest.py 集中管理共享 fixtures: - `temp_dir`: 临时目录(使用 pytest 内置 tmp_path) - `sample_yaml`: 最小可用 YAML 文件 - `sample_image`: 测试图片(使用 Pillow 创建) - `sample_template`: 测试模板文件和目录 - `pptx_validator`: PPTX 验证工具实例 **理由**:集中管理避免重复,便于维护。 ### D3: PPTX 验证方案 创建专门的 PptxFileValidator 工具类(Level 2 验证): - 文件级:存在、可打开 - 幻灯片级:数量、尺寸 - 元素级:类型、数量、内容、位置(容差 0.1 英寸) **理由**:Level 2 平衡了覆盖度和复杂度,无需图像对比库。 ### D4: Preview 测试方案 不启动真实 Flask 服务器,测试以下内容: - `generate_preview_html()` 函数的 HTML 生成 - `create_flask_app()` 的路由配置 - `YAMLChangeHandler` 的文件变化检测(Mock watchdog) **理由**:避免异步服务器的复杂性,测试核心逻辑。 ### D5: Mock 边界 **需要 Mock:** - `webbrowser.open()`(避免打开浏览器) - `watchdog.Observer`(避免文件监听) - CLI 的 `sys.argv`(使用 CliRunner) **不 Mock:** - `python-pptx`(实际生成和验证) - 文件系统(使用临时目录) - `yaml.safe_load()`(实际解析) **理由**:核心生成逻辑必须真实测试,外部依赖可以 Mock。 ### D6: 测试数据组织 ``` tests/fixtures/ ├── yaml_samples/ │ ├── minimal.yaml # 最小示例 │ ├── full_features.yaml # 包含所有功能 │ ├── edge_cases/ # 边界情况 │ └── invalid/ # 无效样本(测试错误处理) ├── templates/ # 测试模板 └── images/ # 测试图片 ``` **理由**:测试数据与代码分离,便于复用和维护。 ### D7: 临时文件清理 方案:使用 pytest 内置 `tmp_path` fixture,自动管理临时目录。 **理由**:pytest 原生支持,无需手动清理代码。 ## Risks / Trade-offs ### Risk 1: PPTX 验证可能不够精确 **描述**:Level 2 验证不检查像素级渲染效果。 **缓解措施**:手动验证关键用例的视觉效果,自动化测试覆盖结构正确性。 ### Risk 2: 测试运行时间较长 **描述**:实际生成 PPTX 文件会增加测试时间。 **缓解措施**:不考虑时间限制,优先保证测试覆盖度。 ### Risk 3: 全局变量影响测试 **描述**:preview/server.py 使用全局变量(app、change_queue 等)。 **缓解措施**:在测试中显式重置全局状态,或重构代码减少全局变量依赖。 ### Risk 4: CLI 测试复杂性 **描述**:yaml2pptx.py 是单体脚本,难以单独导入测试。 **缓解措施**:使用 `subprocess` 运行命令并检查输出/退出码。 ## Migration Plan ### 步骤 1. **配置测试环境** - 更新 pyproject.toml 添加测试依赖 - 创建 tests/conftest.py 2. **实现测试基础设施** - 创建 tests/conftest_pptx.py(PPTX 验证工具) - 创建 tests/fixtures/ 目录和测试数据 3. **实现单元测试** - test_elements.py - test_template.py - test_validators/*.py - test_loaders/test_yaml_loader.py - test_utils.py 4. **实现集成测试** - test_presentation.py - test_rendering_flow.py - test_validation_flow.py 5. **实现端到端测试** - test_convert_cmd.py - test_check_cmd.py - test_preview_cmd.py 6. **更新文档** - README.md 添加测试运行说明 - README_DEV.md 添加测试开发指南 ### 回滚策略 如果测试引入问题: 1. 测试代码位于独立目录,不影响生产代码 2. 可以通过删除 tests/ 目录完全移除 3. pyproject.toml 的测试依赖是可选的 ## Open Questions 无。所有技术决策已明确。