247 lines
10 KiB
Python
247 lines
10 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
测试PDF报告中失败用例详情功能
|
||
"""
|
||
|
||
import json
|
||
import sys
|
||
from pathlib import Path
|
||
from run_api_tests import save_pdf_report
|
||
|
||
def create_test_data_with_failures():
|
||
"""创建包含失败用例的测试数据"""
|
||
|
||
test_data = {
|
||
"overall_summary": {
|
||
"total_endpoints_tested": 3,
|
||
"endpoints_passed": 1,
|
||
"endpoints_failed": 2,
|
||
"endpoints_error": 0,
|
||
"total_test_cases_executed": 8,
|
||
"test_cases_passed": 4,
|
||
"test_cases_failed": 4,
|
||
"test_cases_error": 0,
|
||
"test_case_success_rate": "50%",
|
||
"start_time": "2025-08-07T10:00:00",
|
||
"end_time": "2025-08-07T10:05:00"
|
||
},
|
||
"endpoint_results": [
|
||
{
|
||
"endpoint_id": "POST /api/dms/test/v1/users",
|
||
"endpoint_name": "用户管理接口",
|
||
"overall_status": "失败",
|
||
"duration_seconds": 2.5,
|
||
"start_time": "2025-08-07T10:00:00",
|
||
"end_time": "2025-08-07T10:00:02.5",
|
||
"executed_test_cases": [
|
||
{
|
||
"test_case_id": "TC-AUTH-001",
|
||
"test_case_name": "身份认证验证",
|
||
"test_case_severity": "CRITICAL",
|
||
"status": "失败",
|
||
"message": "缺少必需的请求头 Authorization。API返回401未授权错误,表明身份认证机制未正确实现。建议检查认证中间件配置。",
|
||
"duration_seconds": 0.8,
|
||
"timestamp": "2025-08-07T10:00:00.5"
|
||
},
|
||
{
|
||
"test_case_id": "TC-PARAM-001",
|
||
"test_case_name": "必需参数验证",
|
||
"test_case_severity": "HIGH",
|
||
"status": "失败",
|
||
"message": "请求体缺少必需字段 'username' 和 'email'。服务器应返回400错误并提供详细的字段验证信息,但实际返回了500内部服务器错误。",
|
||
"duration_seconds": 0.6,
|
||
"timestamp": "2025-08-07T10:00:01.1"
|
||
},
|
||
{
|
||
"test_case_id": "TC-RESP-001",
|
||
"test_case_name": "响应格式验证",
|
||
"test_case_severity": "MEDIUM",
|
||
"status": "通过",
|
||
"message": "响应格式符合预期",
|
||
"duration_seconds": 0.3,
|
||
"timestamp": "2025-08-07T10:00:01.7"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"endpoint_id": "GET /api/dms/test/v1/users/{id}",
|
||
"endpoint_name": "用户查询接口",
|
||
"overall_status": "失败",
|
||
"duration_seconds": 1.8,
|
||
"start_time": "2025-08-07T10:00:03",
|
||
"end_time": "2025-08-07T10:00:04.8",
|
||
"executed_test_cases": [
|
||
{
|
||
"test_case_id": "TC-PATH-001",
|
||
"test_case_name": "路径参数验证",
|
||
"test_case_severity": "HIGH",
|
||
"status": "失败",
|
||
"message": "当传入无效的用户ID(如负数或非数字字符串)时,API应返回400错误,但实际返回了500内部服务器错误。这表明输入验证逻辑存在问题,可能导致安全漏洞。",
|
||
"duration_seconds": 0.9,
|
||
"timestamp": "2025-08-07T10:00:03.5"
|
||
},
|
||
{
|
||
"test_case_id": "TC-404-001",
|
||
"test_case_name": "资源不存在处理",
|
||
"test_case_severity": "MEDIUM",
|
||
"status": "通过",
|
||
"message": "正确返回404错误",
|
||
"duration_seconds": 0.4,
|
||
"timestamp": "2025-08-07T10:00:04.4"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"endpoint_id": "DELETE /api/dms/test/v1/users/{id}",
|
||
"endpoint_name": "用户删除接口",
|
||
"overall_status": "通过",
|
||
"duration_seconds": 1.2,
|
||
"start_time": "2025-08-07T10:00:05",
|
||
"end_time": "2025-08-07T10:00:06.2",
|
||
"executed_test_cases": [
|
||
{
|
||
"test_case_id": "TC-DEL-001",
|
||
"test_case_name": "删除权限验证",
|
||
"test_case_severity": "CRITICAL",
|
||
"status": "通过",
|
||
"message": "权限验证正常",
|
||
"duration_seconds": 0.5,
|
||
"timestamp": "2025-08-07T10:00:05.5"
|
||
},
|
||
{
|
||
"test_case_id": "TC-DEL-002",
|
||
"test_case_name": "删除操作验证",
|
||
"test_case_severity": "HIGH",
|
||
"status": "通过",
|
||
"message": "删除操作成功",
|
||
"duration_seconds": 0.4,
|
||
"timestamp": "2025-08-07T10:00:05.9"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"stage_results": [
|
||
{
|
||
"stage_name": "数据一致性检查",
|
||
"description": "验证数据操作的一致性",
|
||
"overall_status": "失败",
|
||
"message": "在并发操作测试中发现数据不一致问题。当多个用户同时创建和删除用户时,数据库中出现了孤立记录。建议实现适当的事务隔离级别和锁机制。",
|
||
"duration_seconds": 3.5,
|
||
"start_time": "2025-08-07T10:00:07"
|
||
},
|
||
{
|
||
"stage_name": "性能基准测试",
|
||
"description": "验证API响应时间",
|
||
"overall_status": "通过",
|
||
"message": "所有API响应时间均在可接受范围内",
|
||
"duration_seconds": 2.1,
|
||
"start_time": "2025-08-07T10:00:10"
|
||
}
|
||
],
|
||
"errors": []
|
||
}
|
||
|
||
return test_data
|
||
|
||
def test_pdf_with_failure_details():
|
||
"""测试包含失败用例详情的PDF报告生成"""
|
||
|
||
print("🧪 测试PDF报告失败用例详情功能")
|
||
print("=" * 60)
|
||
|
||
# 创建测试数据
|
||
test_data = create_test_data_with_failures()
|
||
|
||
# 生成PDF报告
|
||
output_path = Path("test_reports") / "failure_details_test.pdf"
|
||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||
|
||
print(f"📄 生成PDF报告: {output_path}")
|
||
|
||
try:
|
||
save_pdf_report(test_data, output_path, strictness_level='HIGH')
|
||
|
||
if output_path.exists():
|
||
file_size = output_path.stat().st_size / 1024
|
||
print(f"✅ PDF报告生成成功!")
|
||
print(f"📊 文件大小: {file_size:.2f} KB")
|
||
|
||
# 分析测试数据
|
||
total_cases = sum(len(ep.get('executed_test_cases', [])) for ep in test_data['endpoint_results'])
|
||
stage_cases = len(test_data.get('stage_results', []))
|
||
failed_endpoint_cases = sum(1 for ep in test_data['endpoint_results']
|
||
for tc in ep.get('executed_test_cases', [])
|
||
if tc.get('status') in ['失败', 'FAILED'])
|
||
failed_stage_cases = sum(1 for stage in test_data.get('stage_results', [])
|
||
if stage.get('overall_status') in ['失败', 'FAILED'])
|
||
|
||
print(f"\n📋 测试数据统计:")
|
||
print(f"- 总测试用例: {total_cases + stage_cases}")
|
||
print(f"- 端点测试用例: {total_cases}")
|
||
print(f"- Stage测试用例: {stage_cases}")
|
||
print(f"- 失败的端点用例: {failed_endpoint_cases}")
|
||
print(f"- 失败的Stage用例: {failed_stage_cases}")
|
||
print(f"- 总失败用例: {failed_endpoint_cases + failed_stage_cases}")
|
||
|
||
print(f"\n🎯 新增功能验证:")
|
||
print("✅ 失败用例详情分析部分")
|
||
print("✅ 按严重级别分组统计")
|
||
print("✅ 详细失败原因说明")
|
||
print("✅ 用例基本信息展示")
|
||
print("✅ 格式化的失败信息显示")
|
||
|
||
print(f"\n💡 报告包含以下失败用例详情:")
|
||
print("1. TC-AUTH-001: 身份认证验证失败")
|
||
print(" - 严重级别: CRITICAL")
|
||
print(" - 失败原因: 缺少Authorization请求头")
|
||
print("2. TC-PARAM-001: 必需参数验证失败")
|
||
print(" - 严重级别: HIGH")
|
||
print(" - 失败原因: 缺少必需字段username和email")
|
||
print("3. TC-PATH-001: 路径参数验证失败")
|
||
print(" - 严重级别: HIGH")
|
||
print(" - 失败原因: 输入验证逻辑问题")
|
||
print("4. 数据一致性检查Stage失败")
|
||
print(" - 严重级别: HIGH")
|
||
print(" - 失败原因: 并发操作数据不一致")
|
||
|
||
return True
|
||
else:
|
||
print("❌ PDF报告生成失败")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"❌ 生成PDF报告时出错: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def main():
|
||
"""主函数"""
|
||
print("🚀 DMS合规性测试工具 - PDF失败用例详情测试")
|
||
print("=" * 80)
|
||
|
||
success = test_pdf_with_failure_details()
|
||
|
||
print("\n" + "=" * 80)
|
||
if success:
|
||
print("🎉 测试完成!PDF报告现在包含详细的失败用例分析")
|
||
print("\n📋 新功能特点:")
|
||
print("- 失败用例统计和分组")
|
||
print("- 详细的失败原因说明")
|
||
print("- 用例基本信息展示")
|
||
print("- 清晰的格式化显示")
|
||
print("- 支持长文本的适当处理")
|
||
|
||
print("\n💡 使用建议:")
|
||
print("- 查看生成的PDF文件中的'失败用例详情分析'部分")
|
||
print("- 失败原因按严重级别分组显示")
|
||
print("- 每个失败用例都有详细的错误信息")
|
||
|
||
sys.exit(0)
|
||
else:
|
||
print("❌ 测试失败,请检查错误信息")
|
||
sys.exit(1)
|
||
|
||
if __name__ == "__main__":
|
||
main()
|