#!/usr/bin/env python3 """ 完整测试套件执行脚本 执行所有测试并生成详细报告。 """ import subprocess import sys import json from datetime import datetime from pathlib import Path from typing import Dict, List, Any class TestSuiteRunner: """测试套件运行器""" def __init__(self): self.results: Dict[str, Any] = {} self.start_time = None self.end_time = None def run_test_module(self, module: str, description: str) -> Dict[str, Any]: """运行测试模块""" print(f"\n{'='*60}") print(f"🧪 {description}") print(f"{'='*60}") cmd = [ "python", "-m", "pytest", module, "-v", "--tb=short", "-q", "--no-header", "--json-report", "--json-report-file=reports/temp_report.json" ] try: result = subprocess.run( cmd, capture_output=True, text=True, timeout=300 ) # 解析结果 passed = result.returncode == 0 output = result.stdout + result.stderr # 统计测试数量 lines = output.split('\n') test_count = 0 for line in lines: if 'passed' in line or 'failed' in line or 'skipped' in line: # 解析测试统计 parts = line.split() for part in parts: if 'passed' in part: test_count += int(part.split()[0]) if part[0].isdigit() else 0 elif 'failed' in part: test_count += int(part.split()[0]) if part[0].isdigit() else 0 print(f"✅ 测试完成: {test_count} 个测试") return { "module": module, "description": description, "passed": passed, "output": output, "test_count": test_count, "timestamp": datetime.now().isoformat() } except subprocess.TimeoutExpired: print(f"❌ 测试超时: {module}") return { "module": module, "description": description, "passed": False, "error": "Timeout", "timestamp": datetime.now().isoformat() } except Exception as e: print(f"❌ 测试失败: {str(e)}") return { "module": module, "description": description, "passed": False, "error": str(e), "timestamp": datetime.now().isoformat() } def run_all_tests(self) -> Dict[str, Any]: """运行所有测试""" self.start_time = datetime.now() print("🚀 开始执行完整测试套件") print(f"开始时间: {self.start_time.strftime('%Y-%m-%d %H:%M:%S')}") # 创建报告目录 Path("reports").mkdir(exist_ok=True) # 定义测试模块 test_modules = [ ("tests/web/test_auth.py", "认证模块测试"), ("tests/web/test_user_management.py", "用户管理测试"), ("tests/web/test_role_management.py", "角色管理测试"), ("tests/web/test_role_management_green.py", "角色管理Green测试"), ("tests/web/test_boundary_conditions.py", "边界条件测试"), ("tests/web/test_performance.py", "性能测试"), ("tests/web/test_integration.py", "集成测试"), ("tests/uniapp/test_almanac.py", "黄历模块测试"), ("tests/uniapp/test_calendar.py", "日历模块测试"), ] # 运行所有测试模块 for module, description in test_modules: result = self.run_test_module(module, description) self.results[module] = result self.end_time = datetime.now() return self.generate_report() def generate_report(self) -> Dict[str, Any]: """生成测试报告""" total_tests = sum(r.get("test_count", 0) for r in self.results.values()) passed_tests = sum(1 for r in self.results.values() if r.get("passed", False)) failed_tests = len(self.results) - passed_tests duration = (self.end_time - self.start_time).total_seconds() report = { "summary": { "total_modules": len(self.results), "passed_modules": passed_tests, "failed_modules": failed_tests, "total_test_cases": total_tests, "duration_seconds": duration, "start_time": self.start_time.isoformat(), "end_time": self.end_time.isoformat(), }, "modules": self.results, "timestamp": datetime.now().isoformat() } # 保存报告 report_file = Path("reports/full_test_report.json") with open(report_file, "w", encoding="utf-8") as f: json.dump(report, f, indent=2, ensure_ascii=False) # 生成HTML报告 self._generate_html_report(report) return report def _generate_html_report(self, report: Dict[str, Any]): """生成HTML报告""" html_content = f"""
总模块数: {report['summary']['total_modules']}
通过模块: {report['summary']['passed_modules']}
失败模块: {report['summary']['failed_modules']}
总测试用例: {report['summary']['total_test_cases']}
执行时间: {report['summary']['duration_seconds']:.2f} 秒
开始时间: {report['summary']['start_time']}
结束时间: {report['summary']['end_time']}
模块: {module}
状态: {"通过" if result.get("passed", False) else "失败"}
测试数: {result.get('test_count', 0)}