result_parser.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import re
  2. import json
  3. from pathlib import Path
  4. from Utils.Log import log_for_api
  5. logger = log_for_api()
  6. class TestResultParser:
  7. """测试结果解析器"""
  8. def __init__(self, results_dir):
  9. self.results_dir = Path(results_dir)
  10. def parse_pytest_output(self, output):
  11. """从pytest输出中解析测试结果"""
  12. results = {
  13. "total": 0,
  14. "passed": 0,
  15. "failed": 0,
  16. "skipped": 0,
  17. "errors": 0,
  18. "duration": 0,
  19. "pass_rate": 0
  20. }
  21. # 尝试从输出中解析结果
  22. try:
  23. # 匹配 pytest 结果摘要行
  24. pattern = r"(\d+) passed.*?(\d+) failed.*?(\d+) skipped"
  25. match = re.search(pattern, output)
  26. if match:
  27. results["passed"] = int(match.group(1))
  28. results["failed"] = int(match.group(2))
  29. results["skipped"] = int(match.group(3))
  30. results["total"] = results["passed"] + results["failed"] + results["skipped"]
  31. # 计算通过率
  32. if results["total"] > 0:
  33. results["pass_rate"] = round((results["passed"] / results["total"]) * 100, 2)
  34. # 尝试解析持续时间
  35. duration_pattern = r"in (\d+\.\d+)s"
  36. duration_match = re.search(duration_pattern, output)
  37. if duration_match:
  38. results["duration"] = float(duration_match.group(1))
  39. except Exception as e:
  40. logger.error(f"解析pytest输出时出错: {e}")
  41. return results
  42. def parse_allure_results(self):
  43. """从Allure结果文件中解析更详细的信息"""
  44. results = {
  45. "suites": [],
  46. "categories": [],
  47. "status_counts": {"passed": 0, "failed": 0, "broken": 0, "skipped": 0, "unknown": 0}
  48. }
  49. try:
  50. # 查找所有result.json文件
  51. result_files = list(self.results_dir.glob("*-result.json"))
  52. for result_file in result_files:
  53. with open(result_file, 'r', encoding='utf-8') as f:
  54. data = json.load(f)
  55. # 统计状态
  56. status = data.get("status", "unknown")
  57. if status in results["status_counts"]:
  58. results["status_counts"][status] += 1
  59. # 收集套件信息
  60. suite_name = data.get("labels", {}).get("suite", "Unknown Suite")
  61. if suite_name not in results["suites"]:
  62. results["suites"].append(suite_name)
  63. except Exception as e:
  64. logger.error(f"解析Allure结果时出错: {e}")
  65. return results