feat(tester): add client journey testing standard

This commit is contained in:
2026-10-15 16:48:54 +08:00
parent baed23d02a
commit ffa7cbd63e
12 changed files with 518 additions and 0 deletions
+24
View File
@@ -18,6 +18,8 @@ from datetime import datetime, timezone
from pathlib import Path
from typing import Any
from journey import CLIENT_SUITES, client_suite, contract_errors, preflight as journey_preflight
try:
import yaml
except ImportError: # pragma: no cover
@@ -781,6 +783,8 @@ def cmd_select(args: argparse.Namespace, root: Path) -> int:
continue
if args.tag and case.get("tag") != args.tag:
continue
if args.suite and client_suite(case) != args.suite:
continue
if args.driver and case.get("driver") != args.driver:
continue
automation = str(case.get("automation") or "automated")
@@ -810,6 +814,11 @@ def cmd_select(args: argparse.Namespace, root: Path) -> int:
selected, together = expand_run_together(meta, cases, selected, skipped, max_i, automation_filter)
journey_gate = journey_preflight(selected, sessions=meta.get("sessions") or {})
if journey_gate["status"] == "blocked":
print(json.dumps({"preflight": journey_gate, "journey_preflight": journey_gate}, ensure_ascii=False, indent=2))
return 2
preflight = mobile_preflight(
root,
meta,
@@ -840,6 +849,7 @@ def cmd_select(args: argparse.Namespace, root: Path) -> int:
"vars": vars_map,
"artifacts": meta.get("artifacts") or {},
"preflight": preflight,
"journey_preflight": journey_gate,
"skipped": skipped,
"run_together": together,
"status_probe": status_probes,
@@ -922,6 +932,17 @@ def validate(root: Path) -> list[str]:
if not isinstance(sessions, dict):
errors.append("catalog.sessions 必须是 mapping")
sessions = {}
client_suites = meta.get("client_suites")
if client_suites is not None:
if not isinstance(client_suites, dict):
errors.append("catalog.client_suites 必须是 mapping")
else:
unknown = sorted(set(client_suites) - set(CLIENT_SUITES))
if unknown:
errors.append("catalog.client_suites 含非法套件: " + ", ".join(unknown))
missing_suites = sorted(set(CLIENT_SUITES) - set(client_suites))
if missing_suites:
errors.append("catalog.client_suites 缺少标准套件: " + ", ".join(missing_suites))
artifacts = meta.get("artifacts")
if artifacts is not None:
if not isinstance(artifacts, dict):
@@ -998,6 +1019,7 @@ def validate(root: Path) -> list[str]:
errors.append(f"{where}: category={cat} 与文件 category={file_cat} 不一致")
if cat and cat_ids and cat not in cat_ids:
errors.append(f"{where}: category={cat} 不在 catalog.categories")
errors.extend(contract_errors(case, sessions=sessions))
if case.get("lifecycle", "active") not in LIFECYCLES:
errors.append(f"{where}: 非法 lifecycle")
if case.get("tag") not in TAGS:
@@ -1275,6 +1297,8 @@ def build_parser() -> argparse.ArgumentParser:
p_sel.add_argument("--category")
p_sel.add_argument("--id", action="append", dest="ids", default=[])
p_sel.add_argument("--tag", choices=TAGS)
p_sel.add_argument("--suite", "--client-suite", dest="suite", choices=CLIENT_SUITES,
help="客户端旅程套件")
p_sel.add_argument("--max-risk")
p_sel.add_argument("--driver", choices=DRIVERS)
p_sel.add_argument(