1
0

test: add comprehensive pytest test suite

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
This commit is contained in:
2026-03-02 23:11:34 +08:00
parent 027a832c9a
commit ab2510a400
56 changed files with 7035 additions and 6 deletions

191
tests/e2e/test_check_cmd.py Normal file
View File

@@ -0,0 +1,191 @@
"""
Check 命令端到端测试
测试 yaml2pptx.py check 命令的验证功能
"""
import pytest
import subprocess
import sys
from pathlib import Path
class TestCheckCmd:
"""check 命令测试类"""
def run_check(self, *args):
"""辅助函数:运行 check 命令"""
cmd = [sys.executable, "-m", "uv", "run", "python", "yaml2pptx.py", "check"]
cmd.extend(args)
result = subprocess.run(
cmd,
capture_output=True,
text=True,
cwd=Path(__file__).parent.parent.parent
)
return result
def test_check_valid_yaml(self, sample_yaml):
"""测试检查有效的 YAML"""
result = self.run_check(str(sample_yaml))
assert result.returncode == 0
assert "验证" in result.stdout or "通过" in result.stdout
def test_check_invalid_yaml(self, temp_dir):
"""测试检查无效的 YAML"""
# 创建包含错误的 YAML
yaml_content = """
metadata:
size: 16:9
slides:
- elements:
- type: text
box: [1, 1, 8, 1]
content: "Test"
font:
color: "red" # 无效颜色
"""
yaml_path = temp_dir / "invalid.yaml"
yaml_path.write_text(yaml_content)
result = self.run_check(str(yaml_path))
# 应该有错误
assert result.returncode != 0 or "错误" in result.stdout
def test_check_with_warnings_only(self, temp_dir):
"""测试只有警告的 YAML验证通过但有警告"""
yaml_content = """
metadata:
size: 16:9
slides:
- elements:
- type: text
box: [8, 1, 3, 1] # 边界超出
content: "Test"
font:
size: 24
"""
yaml_path = temp_dir / "warning.yaml"
yaml_path.write_text(yaml_content)
result = self.run_check(str(yaml_path))
# 应该显示警告但返回 0
assert "警告" in result.stdout
def test_check_with_template(self, temp_dir, sample_template):
"""测试检查使用模板的 YAML"""
yaml_content = f"""
metadata:
size: 16:9
slides:
- template: title-slide
vars:
title: "Test Title"
"""
yaml_path = temp_dir / "test.yaml"
yaml_path.write_text(yaml_content)
result = self.run_check(str(yaml_path), "--template-dir", str(sample_template))
assert result.returncode == 0
def test_check_nonexistent_template(self, temp_dir):
"""测试检查使用不存在模板的 YAML"""
yaml_content = """
metadata:
size: 16:9
slides:
- template: nonexistent
vars:
title: "Test"
"""
yaml_path = temp_dir / "test.yaml"
yaml_path.write_text(yaml_content)
result = self.run_check(str(yaml_path), "--template-dir", str(temp_dir))
# 应该有错误(模板不存在)
assert result.returncode != 0
def test_check_reports_multiple_errors(self, temp_dir):
"""测试检查报告多个错误"""
yaml_content = """
metadata:
size: 16:9
slides:
- elements:
- type: text
box: [1, 1, 8, 1]
content: "Test 1"
font:
color: "red"
- type: text
box: [2, 2, 8, 1]
content: "Test 2"
font:
color: "blue"
"""
yaml_path = temp_dir / "test.yaml"
yaml_path.write_text(yaml_content)
result = self.run_check(str(yaml_path))
output = result.stdout + result.stderr
# 应该报告多个错误
assert "错误" in output or "2" in output
def test_check_includes_location_info(self, temp_dir):
"""测试检查包含位置信息"""
yaml_content = """
metadata:
size: 16:9
slides:
- elements:
- type: text
box: [1, 1, 8, 1]
content: "Test"
font:
color: "red"
"""
yaml_path = temp_dir / "test.yaml"
yaml_path.write_text(yaml_content)
result = self.run_check(str(yaml_path))
output = result.stdout + result.stderr
# 应该包含位置信息
assert "幻灯片" in output or "元素" in output
def test_check_with_missing_required_variable(self, temp_dir, sample_template):
"""测试检查缺少必需变量的模板"""
yaml_content = f"""
metadata:
size: 16:9
slides:
- template: title-slide
vars: {{}}
"""
yaml_path = temp_dir / "test.yaml"
yaml_path.write_text(yaml_content)
result = self.run_check(str(yaml_path), "--template-dir", str(sample_template))
# 应该有错误
assert result.returncode != 0
def test_check_nonexistent_file(self, temp_dir):
"""测试检查不存在的文件"""
result = self.run_check(str(temp_dir / "nonexistent.yaml"))
assert result.returncode != 0