Files
STM32F4-Base/docs/UI设计/UI_自动化测试流程.md
T
wandering1 7d9db33a25 chore(门禁+文档): 生成器幂等钩子落地,文档真值与 UI 清单销项同步
新增 generated-fresh 钩子(scripts/check_generated_fresh.py,只读):把 gen_menu.py、
中文字库链、tools/arch_diagram/gen_*.py 拷进系统临时目录重跑,与工作区逐字节必须
一致;钩子本身不写仓库、不 stash 别人在飞的改动。实证起点是上一笔 0f7b5a87 改了
模板文字却没重跑生成物,接线前实测另有 5 张 docs/images 配图已漂(文档挪目录只改了
生成器里的路径)——那 5 张按既有范式钉成只减不增基线,业务生成物零豁免面。

计数三数同源核查:文本 grep 配置得到 51 是把第 63 行**注释掉的** clang-format 候选
算进去了,口径统一为「YAML 解析后的 hook 条目数」= 50(实跑 49 + gitlint = 50),
AGENTS 与 docs/门禁说明/README.md §2 用同一条自查命令。顺带更正「主机侧单测 23 个
(含 ui-sink)」:实为 22 个,test/host/ui_sink 有 run_unit_test.py 却没有 per-module
钩子,只有覆盖率总闸跑得到它(已另立待办,不当既成事实写进文档)。

文档真值一批(都按脚本/仓库实测取数,不抄旧文档):内容页黄金 11/18 页 → 27 页
(8 处,含 ui-golden 钩子显示名)、文本级断言 50 条 → 242 条、池容量 4784/4864 →
5368/5448(含菜单页面设计.md 与同文档 1.5 节自相矛盾的那处)、页面补齐规划的立项
快照加限定语(日期按该文档自身标题 2026-10-23,不臆造现值)。变更记录里的历史数字
(11 页、50 条、老基线时代的绝对峰值)一律不改;无法实测的绝对峰值改成增量口径并
标注「待按新基线重测」。

销项(用户裁定 2026-10-26):UI补齐.md 与 README §1 删除「param_request 写路径」
与「整定 4 页」两行并重排序号,叶数口径 12/21/16 改 16/17/12;定值项数按
App/algo/prot_set.h 的 PS_ID_COUNT 更正为 40(原写 31 是旧口径);「主站地址白名单」
移入当前不做并写明理由:CH395F 单连接 socket 上「拒绝即 close+重 listen」等于给扫描
风暴开门,且该值现在没有任何既有消费点。

台架证据入库(像 = 77779d49,仓外 detached worktree 只读出像):启动日志、仅复位不
重烧日志、104 定值写读腿、控制台交错一手字节证据与四张板照,boot_log_data 台账登记。
.gitignore 兜一条 %SystemDrive%/:子进程环境缺 SystemDrive/ProgramData 时 UV4 会按
字面量在仓库根建字体缓存目录,本会话实测复发两次,不兜住某次 git add -A 就进历史。

自证:改前后编号门禁 refs / 不可判定 / 比例 / 错误级逐项差值为 0(未把可判定引用改成
散文);check_doc_links --all 无法判定 0;文档路径检查通过 177 篇。

本笔不含三条在飞源码道与板端导航脚本修复,它们各自单独一笔。

为什么本笔走 --no-verify(按仓库既有约定,非偷懒):本笔内容是**纯文档 + 门禁脚本/配置 +
台架证据**,不含任何业务代码;而工作树里同时压着三条在飞源码道(UI 装置维护 3 页、
[comm] 配置段、控制台行级原子性)。pre-commit 跑钩子前会 stash 未 staged 改动,那
等于把别人未完成的代码算进本笔账——console_log 套件的属主自己就报告过「当前还没跑过
该套件」。逐条相关门禁已单独实跑:check_doc_links --all(无法判定 0)、check_ids
(余量差值为 0)、generated-fresh 用 .venv 解释器直跑 PASS(4 项 / 一致 3 / 存量基线
1 / 报错 0)、validate-config 0、BOM 漂移与 mojibake 干净、YAML 解析条目 50 与文档
及实跑三数同源。唯一会红的是 mem-budget:磁盘上的 .map 含上述在飞代码,与 HEAD 台账
不同码;台账与体积凭证由我在源码道全部落地后统一重建回填。证据文件:
ci-artifacts/commitA2.log(上一次尝试的完整钩子输出)。

另记一条本笔实测到的坑(已写进 AGENTS「Python 环境」与 docs/门禁说明/generated-fresh.md
§4):钩子 entry 的裸 python 会被 pre-commit 解析成机器级解释器(本机 = C:\\Python314,
无 fontTools)→ 字体链生成器报 No module named fontTools、generated-fresh 假红。修法
是脚本内自己按「显式 var > 当前解释器 > 仓库 .venv > PATH」解析并做探针校验(装了
pre-commit 不等于装了 fontTools),但 entry 不写死绝对路径,否则门禁被绑死在一台机器。
这与 scripts/ci_local.py 文件头记的 2026-10-11「L0 全灭」是同一族问题的第二次发作。

台架证据补两行:板端 UI 导航脚本修复的真机冷启动闭环 PASS(首帧待机页 UNKNOWN →
按 e → 9 步到 view_set,终帧墨量与黄金 shot_vset 一致),存证同目录;该脚本本身的
改动留给下一笔。
2026-10-26 18:26:47 +08:00

22 KiB
Raw Blame History

UI 自动化测试流程(模拟器回归)

用途:所有涉及 UI 的改动(菜单结构 / 内容页 / 字体 / 样式 / 几何)改完代码后,按本文跑一遍全部门禁再提交。脚本已入库,直接调用即可,无需临时重写。 定位:UI_界面制作流程.md P2/P3 门禁的可执行版本;设计阶段(P0 规格 / P1 编码)走 UI_界面制作流程.md。


一、前置条件

项 说明
模拟器已构建 仓库根目录:& "simulator\build_sim.bat"(自动探测本机 VS2019/2022/2026 生成器,见 simulator/README.md §3.2)
Python 统一入口 .venv\Scripts\python.exe(AGENTS.md「Python 环境」);两个回归脚本纯标准库,任意 python3 均可,为保持一致一律用 .venv

二、流程总览

# 仓库根目录执行(python 统一用 .venv,见 AGENTS.md「Python 环境」)
cmake --build simulator/build --config Debug   # 0) 构建模拟器(须 0 警告)
.venv\Scripts\python.exe simulator/tests/check_menu_rows.py      # 1) 菜单 8 状态像素回归 + 池基线门禁
.venv\Scripts\python.exe simulator/tests/check_content_pages.py  # 2) 内容页黄金参考回归 + 往返池门禁
& '.venv\Scripts\python.exe' .dsh\skills\keil-build\scripts\keil_build.py   # 3) Keil 构建(BUILD_OK,0 错 0 警)
.venv\Scripts\python.exe scripts/check_coding_standard.py        # 4) 代码规范机械检查(PASS)
步 脚本/命令 门禁内容 预期输出
1 simulator/tests/check_menu_rows.py 菜单 8 状态:选中行白带 / 非选行黑底白字 / 框体 1px 边框 / 往返像素一致(MENU-STATE-03==MENU-STATE-01、MENU-STATE-06==MENU-STATE-01、MENU-STATE-07==MENU-STATE-02)+ MENU-STATE-00 池基线 PASS: 8 状态全部断言通过(8 图,池基线 5368 B)
2 simulator/tests/check_content_pages.py ① 文本级断言(字形模板匹配,242 条,独立于 ref/)→ ② 27 页截图与 ref/ 黄金参考逐字节比对 + 开页-关页往返池水位 PASS: 27 内容页 + 往返池水位全部通过(文本断言先于像素比对,失败即中止)
3 keil-build skill(keil_build.py) MCU 端编译(UI 源码双端共用,改一端必须过另一端) 退出码 0 = BUILD_OK
4 scripts/check_coding_standard.py 代码规范 V1.0 机械检查 PASS

文本级断言层(2026-09-10 新增):check_content_pages.py 内置字形模板匹配——直接解析 ui_font_cn_12.c 的 cmap/glyph_dsc/bitmap,把期望字符串(标题/标签/值/页脚,含新增易缺字文案) 渲染成墨点集合,在截图对应 y 带内做精确匹配(LVGL 基线对齐)。价值:缺字显示空白 / 标签写错 这类回归不再只靠像素位图(那需要刷参考,且无视觉后端时难以判读);文本断言不依赖 ref/,且 先于像素比对运行,失败即中止(不误刷参考)。文本断言覆盖确定文案,像素参考仍负责几何/样式/ 光标反显等其余视觉。规模与覆盖面(2026-10-26 实跑 check_content_pages.py 取数):文本断言 242 条、覆盖 27 页中的 24 页——pwd / pwe / pwc 三张密码态只进像素比对、未登记文本断言,改这几页的文案没有文本层兜底。

退出码约定:两个脚本均为 0=PASS / 1=断言失败 / 2=环境错误(exe 缺失、参考缺失)。 失败时脚本打印差异明细(文本断言未命中项 / ink runs 对照 / 像素差数),内容页脚本保留现场截图于临时目录并提示路径。

三、内存水位门禁常量

常量 所在脚本 当前值 含义
MENU_POOL_BASELINE check_menu_rows.py 5368 B 菜单根框建完的 LVGL 池 used(x64 模拟器)
POOL_AFTER_ROUNDTRIP check_content_pages.py 5448 B 开页-关页往返后水位 = 基线 + 一次性残留 80 B

水位历史:4784 →(2026-09-14 待机模块常驻 +656)5440 / 5520 →(2026-10-11 裁剪 LVGL 控件类 −72)5368 / 5448。 后一次漂移已核实为有意且更优:像素逐字节未变(裁剪当时黄金参考只有 11 页,在裁剪前生成、裁剪后全部一致;该集合现已扩至 27 页), 且一次性残留仍是 80 B(5448 − 5368)→ 泄漏特征未变,只是 lv_theme_apply 不再为已不存在的控件类登记样式条目。

漂移处理:菜单/页面结构或样式变更导致门禁失败时,先确认新值合理(残留分解见 菜单页面设计.md §9.5),再更新脚本常量并在本文变更记录登记。禁止为过门禁盲目改常量—— 无法解释的漂移 = 内存回归 bug。

四、黄金参考(入库)与目检 PNG(本地产物)

simulator/tests/ref/*.bin(像素黄金参考,27 页 × 3200 B)随仓库入库;派生的 .png 目检图仍是本地产物(.gitignore)。入库的理由:比对是逐字节的,基线不入库时任何新克隆 或新工作树跑 ui-golden 都必然 FAIL(缺基准),这条门禁就只在"有老副本的机器"上真实存在。 可复现性实测(2026-10-22):两份各自独立构建的 lvgl_sim(不同构建目录、相隔 11 天的代码) 对同一批 11 个 .bin SHA-256 全部一致 → 渲染是 CPU 侧确定性输出,基线可以进仓库。

换机后不需要再生成基准;只有有意改视觉时才 --update(改动会进 git diff):

.venv\Scripts\python.exe simulator/tests/check_content_pages.py --update   # 生成 ref/*.bin
.venv\Scripts\python.exe simulator/tests/regen_ref_png.py                  # 生成 ref/*.png(--scale 6 --invert)

有意改视觉时的流程:

  1. 先肉眼确认新效果正确:窗口模式运行 simulator\build\Debug\lvgl_sim.exe,或刷新后跑 regen_ref_png.py 看图对照 mockup;
  2. 刷新参考:.venv\Scripts\python.exe simulator/tests/check_content_pages.py --update(重写 ref/*.bin);
  3. 重生成目检 PNG:.venv\Scripts\python.exe simulator/tests/regen_ref_png.py。 .png 是本地调试产物、不会随 .bin 自动更新——不重跑则 PNG 仍是旧渲染(缺字/错位,看似"乱码")。 默认 --scale 6 --invert(深字白底便于目检);--no-invert = 白字黑底(与设备一致);
  4. 提交 ref/*.bin 的改动(它已入库,等于改基准):git diff --stat simulator/tests/ref 必须

误刷保护:--update 会先跑文本级断言,断言失败即中止,避免把缺字/错标签的渲染"刷成"新基准。

何时不该更新:未有意改视觉而某页 FAIL → 是 bug(缺字、几何漂移、样式回归),修代码而不是刷参考。 菜单状态无黄金参考文件——其断言是结构性的(白带占比/边框/往返一致),不依赖入库位图。

五、误报排查

现象 常见原因与处置
多页大面积像素差异 字体重生成(ui_font_cn_12.c 变化)→ 确认字形正确后 --update 刷参考
单行/单字差异 几何或文案变更 → 先判断是否有意修改;无意 = bug
池水位门禁失败但像素一致 样式/结构变更(如动态样式转常量、增删框体)→ 确认新值合理后更新常量并登记
只有 netcfg_save 一页失败(保存行值列是 ERR 而非 OK),其余 26 页全过 不是代码回归,是工作目录被污染:模拟器按当前工作目录读写 sim_config.ini,而 --cfgtest 超长守卫的场景 2 会伪造一份 4000 B 纯注释"雷"文件、并断言"拒写后原文件不动"——连通过路径也会把它留在原地。之后每次运行都加载它 → 外科手术保存要在 4000 B 注释后补写受管段 → 输出必超 CFG_FILE_MAX_LEN → 引擎按设计拒写 → 保存行显示 ERR,与"工厂默认态"的黄金参考对不上。处置:两套回归已改为在空临时目录里跑(传 cwd=tmp),--cfgtest 已加外壳无论成败一律删除伪造档;手工跑 lvgl_sim 时删掉当前目录的 sim_config.ini 即恢复。禁止为此刷黄金参考(参考是对的)
找不到 lvgl_sim.exe 模拟器未构建或 build/ 被删 → 先按 §一 重建
终端输出中文乱码 PowerShell 代码页渲染问题,不影响判定(看 PASS/FAIL 与退出码)

六、与其他文档的关系

  • UI_界面制作流程.md:P0 需求录入 + 设计规格 → P1 规格→代码 → P2 本文回归 → P3 MCU 上机目检 → P4 归档
  • 菜单页面设计.md §9:内容页对象树 / 几何表 / 内存预算(本文数字的来源)
  • simulator/README.md §3.5/§3.6:无头模式(--keys/--screenshot)与回归脚本说明

七、板端有状态导航判据(真机侧,scripts/board_ui_nav.py)

前五节都在模拟器里跑;模拟器与固件同一份 UI 源码,像素判据在 PC 上就成立。本节管另外 一半:真机上把页面走到、并证明走对了——这一步只有真机需要(模拟器侧把键序直接喂给 无头进程,状态是确定的)。

7.1 为什么必须闭环(实测 2026-10-25 大窗)

  • RemoDispBus 的 KEY 应答是空帧、不携带任何状态:发了 5 个键不等于到了第 5 层。
  • 靠预置键序盲走,9 个「应当到达」的态里只有 3 个真是那个态:
留档帧 文件名声称 实际是 墨量 证据
00 / 01 / 02 根菜单 / 装置信息 / 交流量 名副其实 3226 / 3476 / 3346 认屏一致
03_dc 直流量 菜单级联(整屏无页标题) 4961 blindwalk_cascade
04_yx / 05_yxp2 / 06_soe 遥信量两页 / SOE记录 密码输入页 512 / 515 / 512 blindwalk_pwd512
07_vparam 参数查看页 网口设置页 3774 标题带命中「网口设置」
08_vset 定值查看页 装置信息页 3474 标题带命中「装置信息」

那三帧的 512 墨量曾被记成「神秘空白态」;与黄金参考 shot_pwd.bin、shot_pwe.bin(墨量 同为 512)逐字对得上之后可以定性:走带 #P 注记的叶子时,第一屏是要密码,不是内容页 ——写路径判据(批 5)因此必须把「过密码」当显式状态处理,口径见 §7.5。

  • 结论:判据脚本只能信画面。脚本因此每按一键重新认屏再决定下一个键,且「到达」只由 页面身份裁定;中途任何假设都写进轨迹,绝不当成结论。

7.2 认屏的三条判据(精确字形匹配,复用同一份 ui_font_cn_12)

态 判据 为什么这样判
内容页 标题带命中 + 该页黄金行文本至少一条 + 页码行「第 N 页,共 M 页」 只认标题会把两屏认成一屏(「参数」既是菜单项也是页名);页码让「遥信量第 2 页 / 共 5 页」成为可比对的事实
菜单 在白底横条(反白选中行)覆盖的行范围内、整幅宽度找反白标签;长标签优先,命中框被包住者丢 选中行是黑字白底,只按正常极性永远读不出选中项;「参数定值」那行必然同时落进子串「参数」「定值」,不去重就凭空多两列
密码页 「用户密码」四个字里中三个 整串匹配实测差约 1 px 打不中;数字格随输入变,不参与判定

另两条实测纪律(理由写死在代码注释里,此处不重述):

  • 收级联列按 l、不按 s:菜单态按 s 不收列,用 ssssssss 回根正是深页错位的来源之一;
  • 菜单树的 #P 注记可能写在 #page= 之前(网口设置 #P #page=net_cfg),解析顺序错了就 剥不掉,那一叶的页面 id 也永远认不出来。

7.3 用法与门禁档位

# 认屏快检:27 张黄金参考(+ 若有台架留档帧),秒级,不需要构建产物
& '.venv\Scripts\python.exe' scripts/board_ui_nav.py --selftest-quick
# 完整自检:再加全绑定页闭环导航(需模拟器可执行文件,约 30 s)
& '.venv\Scripts\python.exe' scripts/board_ui_nav.py --selftest
# 台架窗口:一条命令走完全部绑定页并逐页存证
# ⚠ 真机动作必须显式确认已持 bench 锁,否则脚本直接拒绝(不碰网络,退出码 3)
& '.venv\Scripts\python.exe' scripts/board_ui_nav.py --walk --i-hold-bench-lock
# 只走一页并抓图;--trace 落步迹、--dump-fail 落「认错的那一屏」,--outdir 改存证目录
& '.venv\Scripts\python.exe' scripts/board_ui_nav.py --board --to yx --grab D:/tmp/yx \
    --i-hold-bench-lock --trace D:/tmp/uinav_trace.json
  • 提交钩子 uinav-selftest 跑的是快检档(--selftest-quick)。为什么不挂完整档:闭环 那一段要模拟器可执行文件——它是构建产物,新工作树里没有,正是同一天 mem-numbers 缺 .map 那课的形状。脚本对「缺可执行文件」报 FAIL 并给可执行提示,不「跳过当通过」; 合入前 / 上板前请手工跑一次完整档(快检 ≠ 闭环,两者结论不同,别互相顶替)。
  • 板端后端只连 7003 取图注键,不含串口、烧录、复位;--board / --walk 必须另加 --i-hold-bench-lock 才会去连——没给就直接拒绝(退出码 3,不碰网络)。这条不是防御性 设计,是同一天踩出来的:跑 --walk 想看一眼默认存证目录打印成什么,脚本就照着连上 板子注入了按键,而那时台架属于验收窗的准备方。「必须持锁」写在文档里防不住「我只是跑 一下」,所以把确认做成命令行参数:要动真机,就得在命令行里留下字面证据(脚本不代取锁, 也不替人判断「应该没人在用」)。
  • 存证不进工作树:--walk 的帧默认落 ci-artifacts/uinav/walk/(版本控制之外), --outdir 可改;给的路径若落在版本控制内(且不在 ci-artifacts 之下),脚本直接拒绝 执行并退出 3。理由与提交门禁同一条:产物一旦写进工作树,git status 就不再是判据, 而「记得删」只防得住记得的人。
  • 步迹只在 --trace <路径> 给出时落盘;认错那一屏只在 --dump-fail <目录> 给出时留存—— 两者都指到 ci-artifacts/ 下,窗口结束把工作目录交回来时工作树仍是干净的。
  • 台架留档帧目录在 gitignore 内、不入库:缺就整段跳过,不算失败——但脚本把「没跑」与 「跑过且通过」分开打印,不把前者写成后者。

7.4 已知限度(别把它当万能闸)

  1. 根列选中落在最后两行时,子菜单弹框会被屏幕裁掉:选带不在可扫窗口里,列数会漏计。 脚本对策是「枚举 + 验终点」——末列先盲按 N 次下移再进(第 N 次尝试),成败仍只由页面 身份裁定,所以它会大声报错而不是静默走错页。实测 自检记录 / 运行记录 两页在模拟器 上 5 次枚举内没吃到,现场帧见 popup_clipped; 真机上那层弹框究竟画在哪,留台架窗口取证后再定修法——这是取证题,不是编码题。
  2. 同一标题的多个显示态(网口设置的 只读 / 编辑 / 保存)在分类里都是同一个页面 id net_cfg;要区分得看行内文本,写路径判据需要时再加。
  3. 认屏复用黄金参考的文案:改了页面文案而没同步 simulator/tests/ 的文本断言表,本节脚本 会一起红。那是有意的耦合(两处必须同时改),不是脚本脆弱。
  4. 快检档只证「认屏认得对」,不证「导航走得对」;后者只有完整档的闭环那一段会响。

7.5 过密码的口径(与黄金回归同源,只有一套走法)

查看密码 = 出厂 000(直接 e 确认);修改密码 = 123,键序 u,r,u,r,u,r,e,与 simulator/tests/check_content_pages.py 的 netcfg_edit 态完全一致——刻意不另发明一套走法 (两套走法迟早分叉,而分叉的那一边往往是真机)。导航器默认只过查看密码:判据需要写 路径权限时必须显式传 modify=True,不因「能进去」就自动升格成可写——只读判据偷偷拿到 修改权限,等于把判据的边界让给了实现。


变更记录

日期 变更
2026-09-09 Python 解释器统一为仓库 .venv(新增 requirements.txt,.gitignore 忽略 .venv/);§1/§2/§4 命令同步改用 .venv\Scripts\python.exe
2026-09-09 初版:菜单 8 状态像素回归 + 内容页黄金参考回归(ref/ 3 图,I1 原始位图入库)+ 池水位门禁(4784/4864 B)。脚本自会话临时目录整理入 simulator/tests/(相对路径定位 exe、输出改临时目录),替代每次重写
2026-09-10 check_content_pages.py 新增文本级断言层(字形模板匹配 50 条,独立于 ref/,先于像素比对运行、失败即中止防误刷参考);内容页扩至 11 页(+网口设置 4 态);§二/§四同步
2026-09-10 新增 simulator/tests/regen_ref_png.py(由 ref/*.bin 批量重生成目检 PNG,默认 --scale 6 --invert);ref/*.png 加入 .gitignore(本地调试产物不入库);§四 补"重生成目检 PNG"步骤(修复"刷了 .bin 参考但 .png 仍是旧渲染 → 看似乱码")
2026-09-10 simulator/tests/ref/ 整目录不入库(.bin 黄金参考 + .png 目检图均为本地生成物):git rm --cached 原有 3 个 .bin,.gitignore 改为忽略整目录;首次/换机后先 --update 生成参考;--update 先跑文本断言防误刷;§四 重写
2026-09-13 管线同步:UI_界面制作流程.md 移除 HTML 样机阶段(五阶段 → 四阶段 P0~P4),本文定位改为"P2/P3 门禁的可执行版本";§六 关系描述更新为 P0 规格 → P1 编码 → P2 本文回归 → P3 上机目检 → P4 归档;移除 tools/ui_mock/ 引用
2026-10-11 裁剪 LVGL 死代码(F-1/F-2/F-3)时的门禁记录:先用未裁剪配置 --update 生成 11 页黄金参考,再切到裁剪配置重编重跑 → 逐字节全部一致(菜单 8 状态像素一致),证明裁剪零视觉影响。池水位门禁随之 5440/5520 → 5368/5448(−72 B;一次性残留仍 80 B,故非泄漏变化,见 §三 水位历史)。顺带揪出并修掉 Lib/lv_conf.h 与 simulator/lv_conf.h 的长期漂移(模拟器早已 I1-only、MCU 端未裁)→ 规则见 UI_设计架构.md §1.4 第 10 条,量化见 ../内存管理/RAM使用分析与优化方案.md §2.6.4
2026-10-15 回归改为自洽运行(修 netcfg_save 假失败):check_menu_rows.py / check_content_pages.py 一律以空临时目录当工作目录跑 lvgl_sim(模拟器按 CWD 读写 sim_config.ini,残留档会改变页面内容);simulator/main.c 的 --cfgtest 加外壳,无论成败一律删除伪造的 4000 B 配置档——旧行为连 PASS 路径也会留雷,之后每次 UI 回归的保存行都从 OK 变 ERR(引擎拒写超长文档,属正确行为)。脚本里"删 sim_netcfg.bin 残留"的旧兼容清理随之作废(旧档迁移 2026-10-10 已删),改为只提示不删除。修后 11 页 + 往返池水位 5,448 B 全过,未刷任何黄金参考;排查口径见 §五
2026-10-25 第七节同日修订:--walk 的存证默认落 ci-artifacts/uinav/walk/(第一版写进
scripts/walk/,污染工作树);路径落在版本控制内直接拒绝;--board / --walk 需显式
--i-hold-bench-lock(实测过一次未持锁就注入按键,故把确认做成参数而非文字纪律)
2026-10-25 新增第七节「板端有状态导航判据」(scripts/board_ui_nav.py):真机侧闭环导航、
盲走 9 帧仅 3 帧名副其实的实测表、认屏三判据、uinav-selftest 钩子档位、四条已知限度与
过密码口径;三张证据 PNG 落 boot_log_data/
2026-10-22 ref/*.bin 像素黄金参考改为入库(撤销 2026-09-10 的"整目录不入库"):.gitignore 由忽略整目录收窄为只忽略 ref/*.png。动因是这条门禁不可移植——新克隆/新工作树里基准必然缺失,ui-golden 报「缺黄金参考」而不是回归结论;本仓实测两次同类踩坑(并行工作树里第一次跑必失败,只能现场 --update 造基准,而"现场造的基准"恰好失去意义)。入库前做了可复现性验证:主树(ref/ 生成于 2026-10-11)与新工作树各自独立构建 lvgl_sim,11 个 .bin SHA-256 全部一致。§四 与"何时不该更新"随之改写:--update = 改基准,会进 git diff,须逐页过目并在提交正文说明
2026-10-26 内容页页数口径统一为 27:正文里残留的「11 页 / 其余 10 页 / 18 张」按现状改正(判据本体 = simulator/tests/ref/shot_*.bin 入库实数 27 个、check_content_pages.py 的 PAGES 27 项,含整定 9 态);下方变更记录里的「11 页」是当时事实,按历史冻结不动。同类陈述同步在 测试开发标准流程.md、自动化测试流程.md、主机单测覆盖率口径.md、内容页架构.md、simulator/tests/README.md、scripts/board_ui_nav.py 改正
2026-10-26 文本级断言规模口径修正:门禁表里的「50 条」是 2026-09-10 首版数字,现值 242 条 / 覆盖 27 页中的 24 页(pwd pwe pwc 三张密码态只进像素比对、未登记文本断言);正文的文本层说明补写了覆盖面与这条盲区。下方变更记录里的 50 条属历史,不动