Add complete test infrastructure for yaml2pptx project with 245+ tests covering unit, integration, and end-to-end scenarios. Test structure: - Unit tests: elements, template system, validators, loaders, utils - Integration tests: presentation and rendering flows - E2E tests: CLI commands (convert, check, preview) Key features: - PptxFileValidator for Level 2 PPTX validation (file structure, element count, content matching, position tolerance) - Comprehensive fixtures for test data consistency - Mock-based testing for external dependencies - Test images generated with PIL/Pillow - Boundary case coverage for edge scenarios Dependencies added: - pytest, pytest-cov, pytest-mock - pillow (for test image generation) Documentation updated: - README.md: test running instructions - README_DEV.md: test development guide Co-authored-by: OpenSpec change: add-comprehensive-tests
5.1 KiB
5.1 KiB
Context
yaml2pptx 项目目前没有测试代码。项目采用模块化架构,包含以下模块:
- core/: 核心领域模型(elements、presentation、template)
- loaders/: YAML 加载层
- validators/: 验证层(geometry、resource、result、validator)
- renderers/: PPTX 和 HTML 渲染
- preview/: Flask 预览服务器
约束条件:
- 必须使用 pytest 框架
- PPTX 文件需要实际生成和验证(Level 2:文件结构、元素数量、内容匹配、位置范围)
- Preview 测试不启动真实服务器
- 临时文件使用系统临时目录并自动清理
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
步骤
-
配置测试环境
- 更新 pyproject.toml 添加测试依赖
- 创建 tests/conftest.py
-
实现测试基础设施
- 创建 tests/conftest_pptx.py(PPTX 验证工具)
- 创建 tests/fixtures/ 目录和测试数据
-
实现单元测试
- test_elements.py
- test_template.py
- test_validators/*.py
- test_loaders/test_yaml_loader.py
- test_utils.py
-
实现集成测试
- test_presentation.py
- test_rendering_flow.py
- test_validation_flow.py
-
实现端到端测试
- test_convert_cmd.py
- test_check_cmd.py
- test_preview_cmd.py
-
更新文档
- README.md 添加测试运行说明
- README_DEV.md 添加测试开发指南
回滚策略
如果测试引入问题:
- 测试代码位于独立目录,不影响生产代码
- 可以通过删除 tests/ 目录完全移除
- pyproject.toml 的测试依赖是可选的
Open Questions
无。所有技术决策已明确。