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
173 lines
5.1 KiB
Markdown
173 lines
5.1 KiB
Markdown
## 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
|
||
|
||
无。所有技术决策已明确。
|