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

View File

@@ -0,0 +1,269 @@
"""
验证流程集成测试
测试完整的验证流程和验证结果收集
"""
import pytest
from pathlib import Path
from validators.validator import Validator
from validators.result import ValidationResult
class TestValidationFlow:
"""验证流程测试类"""
def test_validate_valid_yaml(self, sample_yaml):
"""测试验证有效的 YAML 文件"""
validator = Validator()
result = validator.validate(sample_yaml)
assert isinstance(result, ValidationResult)
assert result.valid is True
assert len(result.errors) == 0
def test_validate_with_warnings(self, temp_dir):
"""测试验证包含警告的 YAML"""
yaml_content = """
metadata:
size: 16:9
slides:
- elements:
- type: text
box: [8, 1, 3, 1] # 右边界超出
content: "Test"
font:
size: 4 # 字体太小
"""
yaml_path = temp_dir / "test.yaml"
yaml_path.write_text(yaml_content)
validator = Validator()
result = validator.validate(yaml_path)
# 应该有警告但 valid 仍为 True没有错误
assert len(result.warnings) > 0
def test_validate_with_errors(self, temp_dir):
"""测试验证包含错误的 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 / "test.yaml"
yaml_path.write_text(yaml_content)
validator = Validator()
result = validator.validate(yaml_path)
assert result.valid is False
assert len(result.errors) > 0
def test_validate_nonexistent_file(self, temp_dir):
"""测试验证不存在的文件"""
validator = Validator()
nonexistent = temp_dir / "nonexistent.yaml"
result = validator.validate(nonexistent)
assert result.valid is False
assert len(result.errors) > 0
def test_collect_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)
validator = Validator()
result = validator.validate(yaml_path)
# 应该收集到多个错误
assert len(result.errors) >= 2
def test_error_location_information(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)
validator = Validator()
result = validator.validate(yaml_path)
# 错误应该包含位置信息
if result.errors:
assert "幻灯片 1" in result.errors[0].location
def test_validate_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)
validator = Validator()
result = validator.validate(yaml_path, template_dir=sample_template)
assert isinstance(result, ValidationResult)
# 有效模板应该验证通过
assert len(result.errors) == 0
def test_validate_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)
validator = Validator()
result = validator.validate(yaml_path, template_dir=sample_template)
# 应该有错误(缺少必需的 title 变量)
assert len(result.errors) > 0
def test_categorize_issues_by_level(self, temp_dir):
"""测试按级别分类问题"""
# 创建包含错误和警告的 YAML
yaml_content = """
metadata:
size: 16:9
slides:
- elements:
- type: text
box: [1, 1, 8, 1]
content: "Test"
font:
color: "red" # 错误
size: 4 # 警告
"""
yaml_path = temp_dir / "test.yaml"
yaml_path.write_text(yaml_content)
validator = Validator()
result = validator.validate(yaml_path)
# 应该同时有错误和警告
assert len(result.errors) > 0
assert len(result.warnings) > 0
def test_format_validation_result(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)
validator = Validator()
result = validator.validate(yaml_path)
# 格式化输出
output = result.format_output()
assert "检查" in output
if result.errors:
assert "错误" in output
if result.warnings:
assert "警告" in output
def test_validate_image_resource(self, temp_dir, sample_image):
"""测试验证图片资源"""
yaml_content = f"""
metadata:
size: 16:9
slides:
- elements:
- type: image
box: [1, 1, 4, 3]
src: "{sample_image.name}"
"""
yaml_path = temp_dir / "test.yaml"
yaml_path.write_text(yaml_content)
validator = Validator()
result = validator.validate(yaml_path)
# 图片存在,应该没有错误
assert len(result.errors) == 0
def test_validate_missing_image_resource(self, temp_dir):
"""测试验证不存在的图片资源"""
yaml_content = """
metadata:
size: 16:9
slides:
- elements:
- type: image
box: [1, 1, 4, 3]
src: "nonexistent.png"
"""
yaml_path = temp_dir / "test.yaml"
yaml_path.write_text(yaml_content)
validator = Validator()
result = validator.validate(yaml_path)
# 应该有错误(图片不存在)
assert len(result.errors) > 0
assert any("图片文件不存在" in e.message for e in result.errors)