From bb9ce8a117f2706cb7afe5ba6a2453d26ff1882c Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Fri, 6 Nov 2026 03:21:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=B92(QA=20harness=C2=B7B=E8=A6=86?= =?UTF-8?q?=E7=9B=96=E6=80=BB=E8=A7=88=E9=9D=A2=E6=9D=BF+=E6=9C=AC?= =?UTF-8?q?=E4=BD=93=E6=9E=9A=E4=B8=BE=E5=99=A8):=20=E4=B9=89=E5=8A=A1?= =?UTF-8?q?=E5=B1=82=3Dtools/extract=5Fcapability=5Flist.py(README?= =?UTF-8?q?=E8=83=BD=E5=8A=9B=E6=B8=85=E5=8D=95=E5=9B=9B=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=8C=89=E6=97=85=E7=A8=8B=E6=AE=B5=E8=A7=A3=E6=9E=90,7?= =?UTF-8?q?=E6=AE=B5103=E8=A1=8C,=E7=94=A8=E4=BE=8B=E6=8C=87=E9=92=88?= =?UTF-8?q?=E5=89=A5=E5=8F=8D=E5=BC=95=E5=8F=B7);=20=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E5=B1=82=3Dtools/coverage=5Freceipts.py=E5=85=AD=E6=BA=90?= =?UTF-8?q?=E5=9B=9E=E6=89=A7=E6=98=8E=E7=BB=86=E5=8C=96(=E5=86=92?= =?UTF-8?q?=E7=83=9F/=E5=8D=95=E5=85=83=E9=9B=86=E6=88=90/=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F/=E6=8E=A2=E9=92=88/=E6=B8=B2=E6=9F=93/=E9=9D=99?= =?UTF-8?q?=E6=80=81=E5=90=84=E4=B8=80.js,=E5=90=8D=C3=97=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=C3=97=E8=AE=A1=E6=95=B0=E7=B2=92=E5=BA=A6,=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E7=BC=BA=E5=A4=B1=3Dnot=5Frun=E4=BA=AE=E7=81=B0?= =?UTF-8?q?=E4=B8=8D=E5=86=92=E5=85=85=E7=BB=BF)+run=5Fall=5Fgates.sh?= =?UTF-8?q?=E6=9C=AB=E5=B0=BE=E6=8C=82=E7=82=B9(=E8=A7=82=E6=B5=8B?= =?UTF-8?q?=E4=BB=B6=E9=9D=9E=E5=88=A4=E5=AE=9A=E4=BB=B6,=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=A4=B1=E8=B4=A5=E6=89=93=E7=BA=A2=E5=AD=97=E4=B8=8D?= =?UTF-8?q?=E7=BF=BB=E9=97=B8=E5=88=A4)+probe=5Fmanifest.js(=E9=9D=A2?= =?UTF-8?q?=E6=9D=BFfile://=E6=97=A0=E6=B3=95=E5=88=97=E7=9B=AE=E5=BD=95,?= =?UTF-8?q?=E6=8C=89=E7=8E=B0=E5=AD=98=E7=99=BB=E8=AE=B0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=90=BD=E6=B8=85=E5=8D=95);=20=E6=9C=BA=E5=99=A8=E4=B9=89?= =?UTF-8?q?=E5=8A=A1=E5=8F=8C=E6=BA=90=E4=B9=8B=E6=9C=AC=E4=BD=93=E6=BA=90?= =?UTF-8?q?=3Dtools/coverage=5Fenum.py(=E4=B8=A4=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E5=99=A8+=E6=AF=94=E5=AF=B9:.tres=E8=A1=8C=E9=9B=86/schema?= =?UTF-8?q?=E8=AF=8D=E8=A1=A8=E5=AD=97=E6=AE=B5/tscn=E6=8C=89=E9=92=AE/gui?= =?UTF-8?q?=5Finput=E8=87=AA=E7=BB=98=E7=B1=BB/=E5=B1=8F=E6=A8=A1=E6=80=81?= =?UTF-8?q?=E6=B8=85=E5=8D=95=C3=97extract=5Fchecks=E6=96=AD=E8=A8=80?= =?UTF-8?q?=E6=96=87=E6=96=99,865=E5=AE=9E=E4=BD=93/=E7=BC=BA=E5=8F=A3212)?= =?UTF-8?q?;=20=E5=91=88=E7=8E=B0=E5=B1=82=3Dtools/coverage=5Freport.html(?= =?UTF-8?q?=E5=9B=9B=E8=8A=82:=E5=85=AD=E5=B1=82=E9=97=B8=E5=86=B5/?= =?UTF-8?q?=E8=83=BD=E5=8A=9B=E8=A1=8C=C3=97=E5=85=AD=E5=B1=82=E7=81=AF?= =?UTF-8?q?=E6=8C=89=E6=97=85=E7=A8=8B=E6=AE=B5/=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E4=B8=8B=E9=92=BB=E4=BA=A4=E4=BA=92=E6=BA=90+=E6=B8=B2?= =?UTF-8?q?=E6=9F=93golden=E5=B1=95=E7=A4=BA=E6=BA=90/=E6=9C=AC=E4=BD=93?= =?UTF-8?q?=E5=AF=B9=E8=B4=A6=E7=BC=BA=E5=8F=A3=C3=97=E6=8E=A2=E9=92=88?= =?UTF-8?q?=E5=91=BD=E4=B8=AD=E9=99=8D=E7=BA=A7=E6=8E=A2=E9=92=88=E6=89=BF?= =?UTF-8?q?=E8=BD=BD;=E7=8A=B6=E6=80=81=E7=81=AF=E5=9B=9B=E6=80=81+?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=97=B6=E9=97=B4=E6=88=B3=E9=99=88=E6=97=A7?= =?UTF-8?q?=E5=8F=AF=E8=A7=81+=E5=AE=8C=E5=A4=87=E6=80=A7=E8=BE=B9?= =?UTF-8?q?=E7=95=8C=E9=A1=B5=E7=9C=89;JSONP=E7=9B=B4=E8=BD=BDfile://?= =?UTF-8?q?=E5=8D=B3=E5=BC=80);=20=E8=B1=81=E5=85=8D=3Dtools/coverage=5Fex?= =?UTF-8?q?emptions.js=E4=BA=BA=E5=B7=A5=E7=BB=B4=E6=8A=A4=E6=AF=8D?= =?UTF-8?q?=E7=89=88;=20=E7=99=BB=E8=AE=B0=E4=BB=B6=E6=89=A9seen=E9=9D=A2(?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=E6=A0=91=E5=85=A8=E9=87=8FBaseButton+db?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E8=A1=A8hotspot=5Fkey=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E9=9D=A2=E6=9E=9A=E4=B8=BE,seen-hit=3D=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E4=BD=86=E9=9B=B6=E7=9C=9F=E8=BE=93=E5=85=A5=E8=A6=86=E7=9B=96?= =?UTF-8?q?=E7=BC=BA=E5=8F=A3=E6=95=B0=E6=8D=AE=E6=BA=90)=E3=80=82?= =?UTF-8?q?=E8=AF=BB=E6=95=B0:=20=E4=B8=A4=E6=8E=A2=E9=92=88=E7=AA=84?= =?UTF-8?q?=E8=B7=91=E7=BB=BF(screen=5Fflow=2019=E5=91=BD=E4=B8=AD/116?= =?UTF-8?q?=E5=AD=98=E5=9C=A8,ui=5Fclick=2027=E5=91=BD=E4=B8=AD/91?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E2=80=94=E2=80=94=E5=81=9C=E6=89=8B=E9=92=AE?= =?UTF-8?q?/=E6=A0=91=E8=B4=AD=E4=B9=B0=E9=87=8D=E5=BB=BA=E4=BB=A3?= =?UTF-8?q?=E7=AD=89=E7=9C=9F=E7=BC=BA=E5=8F=A3=E5=9C=A8=E5=86=8C,?= =?UTF-8?q?=E5=BC=83=E5=9B=BE=E5=88=B7=E6=96=B0=E7=A1=AE=E8=AE=A4=E9=93=BE?= =?UTF-8?q?=E8=B5=B0=E8=A7=86=E5=9B=BE=E6=96=B9=E6=B3=95=E5=B1=9E=E8=A1=94?= =?UTF-8?q?=E6=8E=A5=E6=9D=A1=E7=9B=AE=E4=BD=99=E9=A1=B9);=20=E5=85=AD?= =?UTF-8?q?=E6=BA=90=E6=98=8E=E7=BB=86=E5=8C=96=E5=AF=B9=E7=9C=9F=E5=AE=9E?= =?UTF-8?q?=E9=97=B8=E6=97=A5=E5=BF=97=E6=8A=BD=E6=A0=B8(unit82=E5=A5=97?= =?UTF-8?q?=E4=BB=B6/=E7=B3=BB=E7=BB=9F69=E6=A3=80=E6=9F=A5/=E6=8E=A2?= =?UTF-8?q?=E9=92=8810=E6=AE=B5/=E9=9D=99=E6=80=8113=E6=9D=A1/golden?= =?UTF-8?q?=E9=80=90=E5=B1=8FL1-L3);=20=E9=9D=A2=E6=9D=BF=E6=B5=8F?= =?UTF-8?q?=E8=A7=88=E5=99=A8=E7=9C=9F=E5=AE=9E=E5=85=A5=E5=8F=A3=E5=9B=9B?= =?UTF-8?q?=E8=8A=82=E6=B8=B2=E6=9F=93=E9=AA=8C=E8=BF=87;=20=E5=85=A8?= =?UTF-8?q?=E9=87=8F=E6=A1=A3=E9=97=B8=E3=80=90=E9=AA=8C=E6=94=B6=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E3=80=91=E6=97=A0=E6=96=B0=E5=A2=9E=E7=BA=A2(exit=3D0?= =?UTF-8?q?,=E5=9B=9E=E6=89=A7commit=2007d4977f,=E5=85=AD=E6=BA=90?= =?UTF-8?q?=E6=98=8E=E7=BB=86=E5=8C=96=E5=9C=A8=E9=97=B8=E5=86=85=E5=AE=9E?= =?UTF-8?q?=E8=B7=91=3D=E6=8C=82=E7=82=B9=E7=9C=9F=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E9=AA=8C=E8=AF=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/probe/probe_coverage_recorder.gd | 35 ++++ tools/coverage_enum.py | 158 ++++++++++++++++++ tools/coverage_exemptions.js | 11 ++ tools/coverage_receipts.py | 184 +++++++++++++++++++++ tools/coverage_report.html | 226 ++++++++++++++++++++++++++ tools/extract_capability_list.py | 129 +++++++++++++++ tools/run_all_gates.sh | 2 + 7 files changed, 745 insertions(+) create mode 100644 tools/coverage_enum.py create mode 100644 tools/coverage_exemptions.js create mode 100644 tools/coverage_receipts.py create mode 100644 tools/coverage_report.html create mode 100644 tools/extract_capability_list.py diff --git a/game/probe/probe_coverage_recorder.gd b/game/probe/probe_coverage_recorder.gd index feff5ca1..c7f2f27f 100644 --- a/game/probe/probe_coverage_recorder.gd +++ b/game/probe/probe_coverage_recorder.gd @@ -164,6 +164,38 @@ func _bump(key: String) -> void: _hits[key] = int(_hits.get(key, 0)) + 1 +# ---- 场景树全量交互面枚举(控件缺口数据源:seen−hit=「存在但零真输入覆盖」)---- +# 成员面与登记同源:场景树全部 BaseButton(main 建树常驻——未开过的屏的钮也算存在; +# 已接线钮复用接线键防序位错位,未接线者落盘期才补键——落盘是终态动作,序位计数此后不再消费) +# +营地物件(经 db 布局表 hotspot_key 公共数据面枚举;物件命中见 _on_camp_object 的 #物件id 后缀)。 +func enumerate_seen() -> Array[String]: + var keys: Array[String] = [] + _seen_into(_main, keys) + var db = _main.get("db") + if db != null and db.get("presentation") != null: + var layout = db.presentation.camp_scene_layout + if layout != null: + for spec in layout.layers: + var hk: StringName = spec.hotspot_key + var ck := "camp_object#" + String(hk) + if hk != &"" and not keys.has(ck): + keys.append(ck) + return keys + + +func _seen_into(node: Node, keys: Array[String]) -> void: + if node is BaseButton: + var id := node.get_instance_id() + var key := String(_node_keys.get(id, "")) + if key == "": + key = _assign_key(node) + _node_keys[id] = key + if not keys.has(key): + keys.append(key) + for child in node.get_children(): + _seen_into(child, keys) + + # ---- 落盘(JSONP 式 .js——file:// 页面 + + + + + + + + + + + + + diff --git a/tools/extract_capability_list.py b/tools/extract_capability_list.py new file mode 100644 index 00000000..f1fc445e --- /dev/null +++ b/tools/extract_capability_list.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +r"""extract_capability_list.py — 能力清单义务层提取器(B 覆盖总览面板·义务层) + +把 game/tests/README.md「能力清单」的四列表(能力|系统|真实入口|代表用例)按旅程段 +解析成机器可读 JSONP .js,供 tools/coverage_report.html 经