探针测试指南(2026-09-23 起的标准跑法)
给「改完代码怎么验」这件事定的统一入口。 替代过去"挨个 node web/tools/probe_xxx.cjs"的手工跑法。
一、TL;DR —— 三条命令
# 1 改了哪块就跑哪组(最常用)
PROBE_RENDER=d3d11 node web/tools/run_parallel.cjs --suite scene
# 2 提交前门禁(45 个实测全绿的探针,红了就是真出问题)
PROBE_RENDER=d3d11 node web/tools/run_parallel.cjs --suite green
# 3 看有哪些组
node web/tools/run_parallel.cjs --list
为什么要带 PROBE_RENDER=d3d11:走硬件 GPU。实测同样 8 个探针, 软渲染 --jobs 4 要 193.6s 且会出现假红,硬件渲染只要 50.5s 且零假红。 (详见 §4)
平时赶时间用 --suite core(8 个主干探针,约 50 秒)。
二、分组一览
scene 17 个 3D 场景 / 模型 / 相机 / 光影 / 地面 / 场景内标签
scenery 5 个 景致摆放 / 布局编辑模式
build 12 个 建造 / 营造 / 升阶 / 放置区
ui 16 个 界面 / 浮窗 / 坞 / 提示 / 顶栏
member 16 个 门人 / 人物属性 / 装备 / 武学 / 招募
task 6 个 任务 / 过场视频 / 新手引导
combat 1 个 战术网格战斗
account 2 个 账户 / 存档 / 认证
audio 3 个 音频 / 时辰 / 时间流速
prod 2 个 ⚠️ 线上站点(会注册真账号,默认不跑)
green 45 个 实测全绿 —— 可以当门禁
core 8 个 主干冒烟(快)
speed 4 个 轻量探针(最快)
all 70 个 除线上外全部
分组允许重叠(如 probe_build_dock 同时在 build 和 ui)—— 这是故意的, 它同时被两条改动脉络影响。也可组合:--suite ui,member(自动去重)。
三、⚠️ 已知非全绿的 25 个(跑之前就知道,别当成自己改坏的)
总 70 = 45 green + 25 已知非全绿。明细在 web/tools/_probe_suites.cjs 的 STATUS。
| 类别 | 数量 | 含义 | 该怎么办 |
|---|---|---|---|
flaky | 1 | 时好时坏(症状漂移) | 属探针自身缺陷,不能当门禁 |
partial | 2 | 跑通但有断言失败 | 人工判断是否与本次改动有关 |
red | 18 | 有失败 | 同上 |
slow | 4 | 跑完不Sign out(被 180s 超时杀) | 看它最后输出判断断言是否真过 |
怎么用这张表:runner 跑完会自动区分:
- 🔴 新增失败(不在清单里)→ 优先查这些
- ✅ 无新增失败 → 上面全是既有红,与本次改动无关
📌 这一条是整个工具最要紧的设计。项目里有 20+ 个探针当前就是红的, 不区分的话,跑完一片红会让人以为"是我改坏的" ⇒ 去查一个根本不存在的问题。 项目铁律:假红比没警报更费人。
🔴 状态表是「单次快照」,不是「永远如此」
已经抓到两个反例(都是靠"多跑一次"发现的):
| 探针 | 现象 | 性质 |
|---|---|---|
probe_lantern_glow | 连跑 3 次:36/1、36/1、37/0 | flaky —— F5「点光源照亮地面」偶发失败,疑与作品内时辰/灯笼点亮态有关 |
probe_build_cap | 全量实测显示「1s OK」(假象:并发下造档没跑成,走了静默通过路径);--suite green 复核时立刻暴露 | slow —— 单跑 301s 不Sign out |
⇒ 门禁红了:先查是否在已知清单里,再重跑一次确认是稳定红还是偶发。 ⇒ 复核 green 组本身就是一个有效的交叉验证:probe_build_cap 就是这么被抓出来的 (那次 45/46 通过,唯一失败的就是它)。
四、提速是怎么来的(三层叠加)
| 层 | 做了什么 | 收益 |
|---|---|---|
| 1 硬等待 → 条件轮询 | 18 个探针的 waitForTimeout(9000) → waitGameReady | 每个省约 11 秒(-66.9%) |
| 2 e2e 第 5.5 节 → 夹具预置 | 不再真等任务结算(等 16s 但实际需 48s) | 省 60.8 秒,并让下游假红转绿 |
| 3 渲染后端统一 + 并行 | 62 个探针统一渲染开关;--jobs 与渲染配套 | 8 探针 157.1s → 50.5s(3.11×) |
关键实测数据(8 个定点探针):
| 渲染 | 并发 | 墙钟 | 假红 |
|---|---|---|---|
| 软 | 1 | 157.1 s | 无 |
| 软 | 2 | 110.8 s | 无 |
| 软 | 4 | 193.6 s | ❌ 有 |
| 硬 | 2 | 81.0 s | 无 |
| 硬 | 4(默认) | 50.5 s | ✅ 无 |
| 硬 | 8 | 41.7 s | 无 |
为什么软渲染下高并发会「反向变慢」
无头 Chromium 走软渲染时是 CPU 密集的。N 路并发 ⇒ 抢 CPU ⇒ 单探针耗时暴涨 (probe_task_cards 38s→184s)⇒ 探针内依赖超时的断言来不及满足 ⇒ 把原本通过的判成失败(probe_log_dock 从 47过/0败 掉到 45过/2败)。
换硬件渲染后同样的并发就安全了 —— 所以并发数与渲染后端必须配套调。
五、注意事项
1. 🔴 清测试号会打断「依赖历史 fixture」的探针
python tools/clean_test_accounts.py --yes 会清掉全部 @example.com 账号。 若某探针读历史 fixture 里的账号Sign in,清完就会 HTTP 401,且一条断言都不跑 (报错点离真因很远)。
规范:夹具必须现场造档(调 _tmp/mk_xxx_fixture.py),见 probe_build_cap / probe_building_gate / probe_build_tier 的 makeFixture()。
2026-09-23 就因此抓到 probe_build_tier 是漏网之鱼(读历史档),已修。
清完账号后建议跑一遍 --suite green 复核。
2. 状态表维护
改了某个探针、或修掉了某个红 ⇒ 更新 _probe_suites.cjs 的 STATUS。 否则下次跑又会把"刚修好的"当成已知红,或把"刚坏的"当成既有红。
3. prod 组不要进日常流程
probe_prod_assets / probe_prod_tutorial 打线上站点,后者还会注册真账号, 跑完需要 pm2 stop → 清号 → pm2 start。
4. 完整输出在 _tmp/parallel/<探针名>.log
runner 的失败回显只截末尾 60 行,是提示不是证据。 (开发时踩过:回显窗口截断了前 2 条 FAIL,导致误判"多了/少了几条"。)
六、交付物索引
| 文件 | 作用 |
|---|---|
web/tools/run_parallel.cjs | 并行 runner(--suite / --jobs / --list / --timeout) |
web/tools/_probe_suites.cjs | 分组定义 + 实测状态表 |
web/tools/_auth.cjs | waitUntil(条件等待)/ mergeRenderArgs(渲染开关) |
web/tools/_fixture_task.py | 任务日志夹具(e2e 5.5 节用) |
docs/探针提速-硬等待改条件轮询.md | 提速主报告(硬等待 + e2e 夹具) |
docs/探针并行化.md | 并行化报告(含"混合编组陷阱"复盘) |