""" 测试报告生成器模块 提供测试报告生成功能,支持多种报告格式。 """ import json import os from pathlib import Path from typing import Dict, List, Any, Optional from datetime import datetime from dataclasses import dataclass, field, asdict @dataclass class TestResult: """测试结果数据类""" name: str status: str # passed, failed, skipped duration: float = 0.0 start_time: Optional[str] = None end_time: Optional[str] = None error_message: Optional[str] = None traceback: Optional[str] = None screenshot: Optional[str] = None steps: List[Dict[str, Any]] = field(default_factory=list) @dataclass class TestSuite: """测试套件数据类""" name: str tests: List[TestResult] = field(default_factory=list) @property def passed_count(self) -> int: return sum(1 for t in self.tests if t.status == "passed") @property def failed_count(self) -> int: return sum(1 for t in self.tests if t.status == "failed") @property def skipped_count(self) -> int: return sum(1 for t in self.tests if t.status == "skipped") @property def total_count(self) -> int: return len(self.tests) @property def pass_rate(self) -> float: if self.total_count == 0: return 0.0 return (self.passed_count / self.total_count) * 100 class TestReporter: """测试报告生成器""" def __init__(self, report_dir: str = "reports"): self.report_dir = Path(report_dir) self.report_dir.mkdir(parents=True, exist_ok=True) self.suites: Dict[str, TestSuite] = {} self.start_time: Optional[datetime] = None self.end_time: Optional[datetime] = None def start_report(self) -> None: """开始测试报告""" self.start_time = datetime.now() print(f"📝 测试报告开始于: {self.start_time.strftime('%Y-%m-%d %H:%M:%S')}") def end_report(self) -> None: """结束测试报告""" self.end_time = datetime.now() print(f"📝 测试报告结束于: {self.end_time.strftime('%Y-%m-%d %H:%M:%S')}") def add_test_result(self, suite_name: str, result: TestResult) -> None: """添加测试结果""" if suite_name not in self.suites: self.suites[suite_name] = TestSuite(name=suite_name) self.suites[suite_name].tests.append(result) def generate_html_report(self, filename: str = "test_report.html") -> str: """生成HTML报告""" filepath = self.report_dir / filename total_tests = sum(s.total_count for s in self.suites.values()) total_passed = sum(s.passed_count for s in self.suites.values()) total_failed = sum(s.failed_count for s in self.suites.values()) total_skipped = sum(s.skipped_count for s in self.suites.values()) html_content = f"""
生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
通过率: {suite.pass_rate:.1f}% ({suite.passed_count}/{suite.total_count})