"""unit-test 命令 — 执行 ABAP Unit 测试。""" from __future__ import annotations import argparse import logging from sapcli.client import ADTClient from sapcli.types import get_type_config, parse_object_name logger = logging.getLogger("sapcli.commands.unit_test") def _parse_duration(value: str) -> float: """安全解析方法耗时(秒),无法解析返回 0.0。""" try: return float(value) except (TypeError, ValueError): return 0.0 def cmd_unit_test(args: argparse.Namespace, client: ADTClient) -> None: """执行 ABAP Unit 测试并汇总结果。""" name: str = args.name obj_type: str = args.type parsed = parse_object_name(name, obj_type) type_label = get_type_config(obj_type).label print("=" * 60) print(" ABAP Unit 测试") print("=" * 60) print(f" 对象类型: {type_label}") print(f" 对象名称: {parsed.display_name}") print(f"\n → 正在执行 ABAP Unit 测试...") try: result = client.run_unit_test(parsed.obj_uri) except Exception as e: print(f" ✗ 测试执行失败: {e}") return summary = result.get("summary", {}) classes = result.get("classes", []) if not classes: print(" ℹ 未找到测试类(对象可能不包含 ABAP Unit 测试)") return print() for cls in classes: cls_name = cls.get("name") or parsed.display_name methods = cls.get("methods", []) total_duration = sum(_parse_duration(m.get("duration", "")) for m in methods) failed = [m for m in methods if m.get("alert")] if not failed: print( f" ✅ {cls_name} {len(methods)} methods " f"{total_duration:.2f}s PASSED" ) else: print( f" ❌ {cls_name} {len(methods)} methods " f"{total_duration:.2f}s FAILED" ) for m in failed: line_info = f" at line {m['line']}" if m.get("line") else "" print( f" method: {m['name']} FAILED: " f"{m['alert']}{line_info}" ) # 汇总 tests = summary.get("tests", "?") failures = summary.get("failures", "0") errors = summary.get("errors", "0") skipped = summary.get("skipped", "0") print(f"\n {'─' * 50}") print( f" 合计: {tests} 个测试 | 失败 {failures} | 错误 {errors} | " f"跳过 {skipped}" ) print(f" {'─' * 50}")