1
0

fix: 修复测试问题,提升测试通过率

修复内容:
- E2E测试命令执行方式:将 python -m uv run 改为 uv run
- HTML渲染器:添加 & 字符的HTML转义
- Presentation尺寸验证:添加尺寸值类型验证
- PPTX验证器:修复文本框检测兼容性
- 验证结果格式化:修复提示信息显示
- Mock配置:修复表格渲染等测试的Mock配置

测试结果:
- 修复前: 264 通过, 42 失败, 1 错误
- 修复后: 297 通过, 9 失败, 1 错误

剩余9个失败为待实现的功能增强(验证器模板变量验证)
This commit is contained in:
2026-03-03 00:42:39 +08:00
parent f273cef195
commit c73bd0fedd
12 changed files with 318 additions and 401 deletions

View File

@@ -16,6 +16,7 @@ from pptx.enum.shapes import MSO_SHAPE
class PptxValidationError:
"""验证错误信息"""
def __init__(self, level: str, message: str):
self.level = level # 'ERROR' or 'WARNING'
self.message = message
@@ -69,13 +70,16 @@ class PptxFileValidator:
actual = len(prs.slides)
if actual != expected_count:
self.errors.append(
PptxValidationError("ERROR",
f"幻灯片数量不匹配: 期望 {expected_count}, 实际 {actual}")
PptxValidationError(
"ERROR", f"幻灯片数量不匹配: 期望 {expected_count}, 实际 {actual}"
)
)
return False
return True
def validate_slide_size(self, prs: Presentation, expected_size: str = "16:9") -> bool:
def validate_slide_size(
self, prs: Presentation, expected_size: str = "16:9"
) -> bool:
"""验证幻灯片尺寸"""
expected = self.SIZE_16_9 if expected_size == "16:9" else self.SIZE_4_3
actual_width = prs.slide_width.inches
@@ -83,15 +87,19 @@ class PptxFileValidator:
if abs(actual_width - expected[0]) > self.TOLERANCE:
self.errors.append(
PptxValidationError("ERROR",
f"幻灯片宽度不匹配: 期望 {expected[0]}, 实际 {actual_width}")
PptxValidationError(
"ERROR",
f"幻灯片宽度不匹配: 期望 {expected[0]}, 实际 {actual_width}",
)
)
return False
if abs(actual_height - expected[1]) > self.TOLERANCE:
self.errors.append(
PptxValidationError("ERROR",
f"幻灯片高度不匹配: 期望 {expected[1]}, 实际 {actual_height}")
PptxValidationError(
"ERROR",
f"幻灯片高度不匹配: 期望 {expected[1]}, 实际 {actual_height}",
)
)
return False
@@ -113,8 +121,11 @@ class PptxFileValidator:
counts["text_box"] += 1
elif hasattr(shape, "image"):
counts["picture"] += 1
elif shape.shape_type in [MSO_SHAPE.RECTANGLE, MSO_SHAPE.OVAL,
MSO_SHAPE.ROUNDED_RECTANGLE]:
elif shape.shape_type in [
MSO_SHAPE.RECTANGLE,
MSO_SHAPE.OVAL,
MSO_SHAPE.ROUNDED_RECTANGLE,
]:
counts["shape"] += 1
elif shape.has_table:
counts["table"] += 1
@@ -125,10 +136,14 @@ class PptxFileValidator:
return counts
def validate_text_element(self, slide, index: int = 0,
expected_content: Optional[str] = None,
expected_font_size: Optional[int] = None,
expected_color: Optional[tuple] = None) -> bool:
def validate_text_element(
self,
slide,
index: int = 0,
expected_content: Optional[str] = None,
expected_font_size: Optional[int] = None,
expected_color: Optional[tuple] = None,
) -> bool:
"""
验证文本元素
@@ -142,7 +157,8 @@ class PptxFileValidator:
Returns:
验证是否通过
"""
text_boxes = [s for s in slide.shapes if s.shape_type == MSO_SHAPE.TEXT_BOX]
# 通过检查是否有text_frame属性来判断是否是文本框
text_boxes = [s for s in slide.shapes if hasattr(s, "text_frame")]
if index >= len(text_boxes):
self.errors.append(
@@ -158,8 +174,10 @@ class PptxFileValidator:
actual_content = text_frame.text
if actual_content != expected_content:
self.errors.append(
PptxValidationError("ERROR",
f"文本内容不匹配: 期望 '{expected_content}', 实际 '{actual_content}'")
PptxValidationError(
"ERROR",
f"文本内容不匹配: 期望 '{expected_content}', 实际 '{actual_content}'",
)
)
return False
@@ -168,8 +186,10 @@ class PptxFileValidator:
actual_size = text_frame.paragraphs[0].font.size.pt
if abs(actual_size - expected_font_size) > 1:
self.errors.append(
PptxValidationError("ERROR",
f"字体大小不匹配: 期望 {expected_font_size}pt, 实际 {actual_size}pt")
PptxValidationError(
"ERROR",
f"字体大小不匹配: 期望 {expected_font_size}pt, 实际 {actual_size}pt",
)
)
return False
@@ -180,20 +200,25 @@ class PptxFileValidator:
actual_color = (actual_rgb[0], actual_rgb[1], actual_rgb[2])
if actual_color != expected_color:
self.errors.append(
PptxValidationError("ERROR",
f"字体颜色不匹配: 期望 RGB{expected_color}, 实际 RGB{actual_color}")
PptxValidationError(
"ERROR",
f"字体颜色不匹配: 期望 RGB{expected_color}, 实际 RGB{actual_color}",
)
)
return False
except Exception:
self.errors.append(
PptxValidationError("WARNING", "无法获取字体颜色")
)
self.errors.append(PptxValidationError("WARNING", "无法获取字体颜色"))
return True
def validate_position(self, shape, expected_left: float, expected_top: float,
expected_width: Optional[float] = None,
expected_height: Optional[float] = None) -> bool:
def validate_position(
self,
shape,
expected_left: float,
expected_top: float,
expected_width: Optional[float] = None,
expected_height: Optional[float] = None,
) -> bool:
"""
验证元素位置和尺寸
@@ -212,15 +237,17 @@ class PptxFileValidator:
if abs(actual_left - expected_left) > self.TOLERANCE:
self.errors.append(
PptxValidationError("ERROR",
f"左边距不匹配: 期望 {expected_left}, 实际 {actual_left}")
PptxValidationError(
"ERROR", f"左边距不匹配: 期望 {expected_left}, 实际 {actual_left}"
)
)
return False
if abs(actual_top - expected_top) > self.TOLERANCE:
self.errors.append(
PptxValidationError("ERROR",
f"上边距不匹配: 期望 {expected_top}, 实际 {actual_top}")
PptxValidationError(
"ERROR", f"上边距不匹配: 期望 {expected_top}, 实际 {actual_top}"
)
)
return False
@@ -228,8 +255,10 @@ class PptxFileValidator:
actual_width = shape.width.inches
if abs(actual_width - expected_width) > self.TOLERANCE:
self.errors.append(
PptxValidationError("ERROR",
f"宽度不匹配: 期望 {expected_width}, 实际 {actual_width}")
PptxValidationError(
"ERROR",
f"宽度不匹配: 期望 {expected_width}, 实际 {actual_width}",
)
)
return False
@@ -237,8 +266,10 @@ class PptxFileValidator:
actual_height = shape.height.inches
if abs(actual_height - expected_height) > self.TOLERANCE:
self.errors.append(
PptxValidationError("ERROR",
f"高度不匹配: 期望 {expected_height}, 实际 {actual_height}")
PptxValidationError(
"ERROR",
f"高度不匹配: 期望 {expected_height}, 实际 {actual_height}",
)
)
return False
@@ -265,23 +296,21 @@ class PptxFileValidator:
)
if actual_rgb != expected_rgb:
self.errors.append(
PptxValidationError("ERROR",
f"背景颜色不匹配: 期望 RGB{expected_rgb}, 实际 RGB{actual_rgb}")
PptxValidationError(
"ERROR",
f"背景颜色不匹配: 期望 RGB{expected_rgb}, 实际 RGB{actual_rgb}",
)
)
return False
except Exception as e:
self.errors.append(
PptxValidationError("WARNING", f"无法获取背景颜色: {e}")
)
self.errors.append(PptxValidationError("WARNING", f"无法获取背景颜色: {e}"))
return True
def _validate_file_exists(self, pptx_path: Path) -> bool:
"""验证文件存在且大小大于 0"""
if not pptx_path.exists():
self.errors.append(
PptxValidationError("ERROR", f"文件不存在: {pptx_path}")
)
self.errors.append(PptxValidationError("ERROR", f"文件不存在: {pptx_path}"))
return False
if pptx_path.stat().st_size == 0: