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,135 @@
"""
资源验证器单元测试
测试 ResourceValidator 的图片和模板文件验证功能
"""
import pytest
from pathlib import Path
from validators.resource import ResourceValidator
class TestResourceValidator:
"""ResourceValidator 测试类"""
def test_init(self, temp_dir):
"""测试初始化"""
validator = ResourceValidator(yaml_dir=temp_dir)
assert validator.yaml_dir == temp_dir
assert validator.template_dir is None
def test_init_with_template_dir(self, temp_dir):
"""测试带模板目录初始化"""
template_dir = temp_dir / "templates"
validator = ResourceValidator(
yaml_dir=temp_dir,
template_dir=template_dir
)
assert validator.template_dir == template_dir
class TestValidateImage:
"""validate_image 方法测试"""
def test_existing_image(self, temp_dir, sample_image):
"""测试存在的图片文件"""
validator = ResourceValidator(yaml_dir=temp_dir)
elem = type('Element', (), {'src': sample_image.name})()
issues = validator.validate_image(elem, 1, 1)
assert len(issues) == 0
def test_nonexistent_image(self, temp_dir):
"""测试不存在的图片文件"""
validator = ResourceValidator(yaml_dir=temp_dir)
elem = type('Element', (), {'src': 'nonexistent.png'})()
issues = validator.validate_image(elem, 1, 1)
assert len(issues) == 1
assert issues[0].level == "ERROR"
assert issues[0].code == "IMAGE_FILE_NOT_FOUND"
def test_image_with_absolute_path(self, temp_dir, sample_image):
"""测试绝对路径图片"""
validator = ResourceValidator(yaml_dir=temp_dir)
elem = type('Element', (), {'src': str(sample_image)})()
issues = validator.validate_image(elem, 1, 1)
assert len(issues) == 0
def test_image_without_src_attribute(self, temp_dir):
"""测试没有 src 属性的元素"""
validator = ResourceValidator(yaml_dir=temp_dir)
elem = type('Element', (), {})() # 没有 src 属性
issues = validator.validate_image(elem, 1, 1)
assert len(issues) == 0
def test_image_with_empty_src(self, temp_dir):
"""测试空 src 字符串"""
validator = ResourceValidator(yaml_dir=temp_dir)
elem = type('Element', (), {'src': ''})()
issues = validator.validate_image(elem, 1, 1)
assert len(issues) == 0
class TestValidateTemplate:
"""validate_template 方法测试"""
def test_slide_without_template(self, temp_dir):
"""测试不使用模板的幻灯片"""
validator = ResourceValidator(yaml_dir=temp_dir)
slide_data = {} # 没有 template 字段
issues = validator.validate_template(slide_data, 1)
assert len(issues) == 0
def test_template_with_dir_not_specified(self, temp_dir):
"""测试使用模板但未指定模板目录"""
validator = ResourceValidator(yaml_dir=temp_dir, template_dir=None)
slide_data = {'template': 'title-slide'}
issues = validator.validate_template(slide_data, 1)
assert len(issues) == 1
assert issues[0].level == "ERROR"
assert issues[0].code == "TEMPLATE_DIR_NOT_SPECIFIED"
def test_nonexistent_template_file(self, temp_dir):
"""测试不存在的模板文件"""
template_dir = temp_dir / "templates"
template_dir.mkdir()
validator = ResourceValidator(yaml_dir=temp_dir, template_dir=template_dir)
slide_data = {'template': 'nonexistent'}
issues = validator.validate_template(slide_data, 1)
assert len(issues) == 1
assert issues[0].level == "ERROR"
assert issues[0].code == "TEMPLATE_FILE_NOT_FOUND"
def test_valid_template_file(self, sample_template):
"""测试有效的模板文件"""
validator = ResourceValidator(
yaml_dir=sample_template.parent,
template_dir=sample_template
)
slide_data = {'template': 'title-slide'}
issues = validator.validate_template(slide_data, 1)
assert len(issues) == 0
def test_template_with_yaml_extension(self, temp_dir):
"""测试带 .yaml 扩展名的模板"""
template_dir = temp_dir / "templates"
template_dir.mkdir()
(template_dir / "test.yaml").write_text("vars: []\nelements: []")
validator = ResourceValidator(yaml_dir=temp_dir, template_dir=template_dir)
slide_data = {'template': 'test.yaml'}
issues = validator.validate_template(slide_data, 1)
assert len(issues) == 0
def test_invalid_template_structure(self, temp_dir):
"""测试无效的模板结构"""
template_dir = temp_dir / "templates"
template_dir.mkdir()
# 创建缺少 elements 字段的无效模板
(template_dir / "invalid.yaml").write_text("vars: []")
validator = ResourceValidator(yaml_dir=temp_dir, template_dir=template_dir)
slide_data = {'template': 'invalid'}
issues = validator.validate_template(slide_data, 1)
assert len(issues) == 1
assert issues[0].level == "ERROR"
assert issues[0].code == "TEMPLATE_STRUCTURE_ERROR"