generate_test_summary.py 5.48 KB
#!/usr/bin/env python3
"""
生成测试摘要脚本

用于CI/CD流水线中汇总所有测试结果
"""

import json
import os
import sys
import glob
from pathlib import Path
from datetime import datetime
from typing import Dict, Any, List


def collect_test_results() -> Dict[str, Any]:
    """收集所有测试结果"""
    results = {
        'timestamp': datetime.now().isoformat(),
        'suites': {},
        'summary': {
            'total_tests': 0,
            'passed': 0,
            'failed': 0,
            'skipped': 0,
            'errors': 0,
            'total_duration': 0.0
        }
    }

    # 查找所有测试结果文件
    test_files = glob.glob('*_test_results.json')

    for test_file in test_files:
        try:
            with open(test_file, 'r', encoding='utf-8') as f:
                test_data = json.load(f)

            suite_name = test_file.replace('_test_results.json', '')

            if 'summary' in test_data:
                summary = test_data['summary']
                results['suites'][suite_name] = {
                    'total': summary.get('total', 0),
                    'passed': summary.get('passed', 0),
                    'failed': summary.get('failed', 0),
                    'skipped': summary.get('skipped', 0),
                    'errors': summary.get('error', 0),
                    'duration': summary.get('duration', 0.0)
                }

                # 更新总体统计
                results['summary']['total_tests'] += summary.get('total', 0)
                results['summary']['passed'] += summary.get('passed', 0)
                results['summary']['failed'] += summary.get('failed', 0)
                results['summary']['skipped'] += summary.get('skipped', 0)
                results['summary']['errors'] += summary.get('error', 0)
                results['summary']['total_duration'] += summary.get('duration', 0.0)

        except Exception as e:
            print(f"Error reading {test_file}: {e}")
            continue

    # 计算成功率
    if results['summary']['total_tests'] > 0:
        results['summary']['success_rate'] = (
            results['summary']['passed'] / results['summary']['total_tests'] * 100
        )
    else:
        results['summary']['success_rate'] = 0.0

    return results


def generate_text_report(results: Dict[str, Any]) -> str:
    """生成文本格式的测试报告"""
    lines = []

    # 标题
    lines.append("=" * 60)
    lines.append("搜索引擎自动化测试报告")
    lines.append("=" * 60)
    lines.append(f"时间: {results['timestamp']}")
    lines.append("")

    # 摘要
    summary = results['summary']
    lines.append("📊 测试摘要")
    lines.append("-" * 30)
    lines.append(f"总测试数: {summary['total_tests']}")
    lines.append(f"✅ 通过: {summary['passed']}")
    lines.append(f"❌ 失败: {summary['failed']}")
    lines.append(f"⏭️ 跳过: {summary['skipped']}")
    lines.append(f"🚨 错误: {summary['errors']}")
    lines.append(f"📈 成功率: {summary['success_rate']:.1f}%")
    lines.append(f"⏱️ 总耗时: {summary['total_duration']:.2f}秒")
    lines.append("")

    # 状态判断
    if summary['failed'] == 0 and summary['errors'] == 0:
        lines.append("🎉 所有测试都通过了!")
    else:
        lines.append("⚠️ 存在失败的测试,请查看详细日志。")
    lines.append("")

    # 各测试套件详情
    if results['suites']:
        lines.append("📋 测试套件详情")
        lines.append("-" * 30)

        for suite_name, suite_data in results['suites'].items():
            lines.append(f"\n{suite_name.upper()}:")
            lines.append(f"  总数: {suite_data['total']}")
            lines.append(f"  ✅ 通过: {suite_data['passed']}")
            lines.append(f"  ❌ 失败: {suite_data['failed']}")
            lines.append(f"  ⏭️ 跳过: {suite_data['skipped']}")
            lines.append(f"  🚨 错误: {suite_data['errors']}")
            lines.append(f"  ⏱️ 耗时: {suite_data['duration']:.2f}秒")

            # 添加状态图标
            if suite_data['failed'] == 0 and suite_data['errors'] == 0:
                lines.append(f"  状态: ✅ 全部通过")
            else:
                lines.append(f"  状态: ❌ 存在问题")

    lines.append("")
    lines.append("=" * 60)

    return "\n".join(lines)


def generate_json_report(results: Dict[str, Any]) -> str:
    """生成JSON格式的测试报告"""
    return json.dumps(results, indent=2, ensure_ascii=False)


def main():
    """主函数"""
    # 收集测试结果
    print("收集测试结果...")
    results = collect_test_results()

    # 生成报告
    print("生成测试报告...")
    text_report = generate_text_report(results)
    json_report = generate_json_report(results)

    # 保存报告
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")

    # 文本报告
    text_file = f"final_test_report.txt"
    with open(text_file, 'w', encoding='utf-8') as f:
        f.write(text_report)

    # JSON报告
    json_file = f"final_test_report.json"
    with open(json_file, 'w', encoding='utf-8') as f:
        f.write(json_report)

    print(f"测试报告已生成:")
    print(f"  文本报告: {text_file}")
    print(f"  JSON报告: {json_file}")

    # 输出摘要到控制台
    print("\n" + "=" * 60)
    print(text_report)

    # 返回退出码
    summary = results['summary']
    if summary['failed'] > 0 or summary['errors'] > 0:
        return 1
    else:
        return 0


if __name__ == "__main__":
    sys.exit(main())