90 lines
3.1 KiB
Python
90 lines
3.1 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""UAT 计划与执行支撑文档(docs/UAT计划与执行支撑.md,issue #92)一致性检查。
|
||
|
||
检查项:
|
||
1. 必备章节齐全(目标/角色/准入/用例集/执行计划/缺陷/准出/交付物/风险);
|
||
2. 验收流程六节点关键词存在(PRD §10:自测→内部评审→客户UAT→上线→质保观察→闭环);
|
||
3. NFR 量化指标齐全(PRD §9:P99≤1.8s / 丢失率≤0.02% / 可用性≥99.8% / 路由≥96.5% / 首屏≤2s);
|
||
4. 用例覆盖三类场景(监控A/优化B/LLM C)+ NFR + 移动端;
|
||
5. 引用配套资产路径存在(部署手册/采集网隔离文档/healthz 探针)。
|
||
|
||
用法:python _check_uat_plan.py
|
||
"""
|
||
import os
|
||
import sys
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
DOC_PATH = os.path.join(HERE, "UAT计划与执行支撑.md")
|
||
|
||
REQUIRED_SECTIONS = [
|
||
"## 1. 目标与范围",
|
||
"## 2. 角色与职责(RACI)",
|
||
"## 3. 准入条件(Entry Criteria)",
|
||
"## 4. UAT 测试用例集",
|
||
"## 5. 执行计划与排期",
|
||
"## 6. 缺陷管理(Bug Triage)",
|
||
"## 7. 准出条件(Exit Criteria / 放行)",
|
||
"## 8. 交付物清单(UAT 阶段)",
|
||
"## 9. 风险与缓解",
|
||
]
|
||
|
||
# PRD §10 验收流程六节点
|
||
FLOW_KEYWORDS = ["自测", "内部评审", "客户 UAT", "上线", "质保观察", "闭环"]
|
||
|
||
# PRD §9 NFR 量化底线
|
||
NFR_KEYWORDS = ["1.8s", "0.02%", "99.8%", "96.5%", "2s"]
|
||
|
||
# 用例场景覆盖(用例编号前缀)
|
||
SCENARIO_PREFIXES = ["UAT-A-", "UAT-B-", "UAT-C-", "UAT-N-", "UAT-M-"]
|
||
|
||
# 必须存在的配套资产路径(相对仓库根)
|
||
# 注:部署手册(issue #91)随其 PR 合并后存在;本脚本校验本仓库主干已具备的资产。
|
||
ASSET_PATHS = [
|
||
"docs/产品设计文档_iAOP.md", # PRD(UAT 用例依据来源)
|
||
"docs/采集网只读隔离与网闸配置.md", # UAT-N-05 网络只读验证依据
|
||
"deploy/k8s/healthz/probe_availability.py", # UAT-N-02 可用性探针
|
||
]
|
||
|
||
|
||
def main() -> int:
|
||
failures = []
|
||
repo_root = os.path.dirname(HERE)
|
||
|
||
if not os.path.isfile(DOC_PATH):
|
||
print("FAIL\n - UAT 计划文档不存在:UAT计划与执行支撑.md")
|
||
return 1
|
||
|
||
text = open(DOC_PATH, "r", encoding="utf-8").read()
|
||
|
||
for sec in REQUIRED_SECTIONS:
|
||
if sec not in text:
|
||
failures.append(f"缺少必备章节:{sec}")
|
||
|
||
for kw in FLOW_KEYWORDS:
|
||
if kw not in text:
|
||
failures.append(f"缺少验收流程节点关键词:{kw}")
|
||
|
||
for kw in NFR_KEYWORDS:
|
||
if kw not in text:
|
||
failures.append(f"缺少 NFR 量化指标关键词:{kw}")
|
||
|
||
for prefix in SCENARIO_PREFIXES:
|
||
if prefix not in text:
|
||
failures.append(f"用例未覆盖场景前缀:{prefix}")
|
||
|
||
for rel in ASSET_PATHS:
|
||
if not os.path.isfile(os.path.join(repo_root, *rel.split("/"))):
|
||
failures.append(f"配套资产缺失:{rel}")
|
||
|
||
if failures:
|
||
print("FAIL")
|
||
for f in failures:
|
||
print(" -", f)
|
||
return 1
|
||
print("OK: UAT 计划章节/流程节点/NFR指标/场景覆盖/配套资产校验通过")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|