Files
orisys-app/docs/test-repair-rework.zh.md
T
ykcheungab 55dafeb7fb 记录测试修复第 3 轮验收通过
代码审查与哈希核对一致,用户独立运行的门禁 PASS,任务标为 done。
2026-10-18 21:36:57 +08:00

15 KiB
Raw Blame History

Studio 测试修复:第 3 轮返工

状态:done。日期:2026-10-18。前序计划与诊断:测试修复与门禁计划,其阶段 0–6 已交付于 433b76e。 自第 3 轮起,本文件是 task_id test-repair 的权威任务记录,原计划不再维护状态。

1. 为什么返工

验收方(Claude)读了 433b76e 的实际差异,未在 Windows 上复跑。第 2 轮的测试修复大体成立,但以下问题会让门禁或产品行为与声明不符:

# 问题 证据 后果
R1 推送前的门禁不 lint 已提交的改动 gate.ps1 调用 tools/lint_gate.py 时不带 --base;lint_gate.py 第 87–89 行只在给了基准时比较 base...HEAD,否则只看暂存与未暂存差异 pre-push 时要推送的提交从不被检查,反而会检查其他任务未提交的 autocal 文件
R2 叠加底图的粘性失败范围过大 replay_analysis.py 的 overlay_base() 在 project() 第一次返回 None 时就置 _overlay_failed;overlay_base.py 的 finger 投影在单帧 unrolled is None 或任何异常时都返回 None 一帧坏图就让 finger 结果在整个会话里失去叠加视图,超出本任务只处理 box 的范围
R3 新回退逻辑没有测试,采纳时还会闪出拒绝文案 测试中没有引用 overlay_unavailable;serve_stored_view() 先按 ARROW_STITCHED 渲染一次,失败后改 ARROW_PURE 再渲染一次 回退坏了门禁仍是绿的;操作员会短暂看到“采集画面不可用”
R4 门禁与测试数据的小问题 见第 3 节 R4 证据不完整,或门禁结论偏宽

2. 规则

沿用原计划第 2 节全部规则:scratch、固定解释器、不暂存不提交、不改 autocal、不得通过删除或放宽断言、加 skip 或 xfail 让测试变绿。 scratch 仍为 orisys-app/.scratch/test-repair/,本轮运行放在 round3/ 下;开始时写 .active,结束后删除。

3. 返工项

项 要求 验收 估时
R1 lint 基准 gate.ps1 新增 -LintBase 参数,默认 origin/main,传给 lint_gate.py --base。先用 git rev-parse --verify 校验,无效时退出码 2,不得静默退回只看工作区。summary.md 写明 lint 基准和被检查的文件数。pre-push 钩子用默认值;README“合并门禁”一节补一句参数说明 ① gate.ps1 -LintBase HEAD~1 的 lint.log 列出 433b76e 改过的 .py 文件,例如 replay_controller.py;② -LintBase no-such-ref 退出码 2;③ 默认运行退出码 0 1 h
R2 失败范围 只有“再试也不会成功”的失败才粘性:投影器打开失败,或 box 投影失败(第 2 轮实测每帧都失败)。finger 投影单帧返回 None 只影响该帧,下一帧照常尝试。建议由 OverlayBaseProjector 按传感器声明失败是否永久,AnalysisSession 据此决定;不得按异常文本判断 新增不依赖 SDK 的单元测试,用替身投影器:① finger 式投影首帧 None、次帧成功 → 次帧拿到底图,overlay_unavailable 为假;② box 式投影失败一次 → overlay_unavailable 为真,之后不再调用投影;③ 打开失败 → 同 ②。记录 ① 在第 2 轮代码上失败的证据 1.5 h
R3 回退测试 serve_stored_view() 在设置视图之前就确定该结果能否画叠加,只设置一次视图、只渲染一次。新增测试:用 tests/data/box_short_20260930 走真实分析流程采纳 box 结果,断言 ① 最终视图为 ARROW_PURE;② 采纳过程中面板从未显示 panels.arrow_capture_unavailable;③ render_frame 只调用一次;④ 之后手动选 ARROW_STITCHED 仍显示拒绝及原因 新测试的 ② 或 ③ 在第 2 轮代码上失败、修后通过;test_bare_video_analysis.py 现有断言不变且通过 1.5 h
R4 小修 a. tests/data/README.md 的来源改为实际来源 .scratch/result-visible/,注明 dist/ 原件已不可用、无法逐字节比对,并列出 5 个文件的 SHA256;b. gate.ps1 结束时在 finally 中删除 .active,运行号改用 UTC 时间;c. ui_check.py 退出码非 0 时判失败;d. pytest 退出码非 0 而 JUnit 无失败时,只放行 0xC0000005(-1073741819)并在汇总中写明,其他非 0 退出码判失败 a 的哈希与实际文件一致;b–d 各用一次临时构造的场景验证(例如临时让 ui_check.py 以退出码 3 结束),验证后恢复,并用 git diff 确认无残留 1 h

R2 先于 R3;全部完成后以最终状态跑一次 gate.ps1。总预算 5 h,超出 50%(7.5 h)按约定标 blocked。

4. 需用户决定(本轮不执行)

  1. box 叠加画面的断言。 test_bare_video_analysis.py 原断言“箭头画在采集画面上”,第 2 轮改为断言“面板拒绝”。这样产品缺陷在门禁里显示为通过,修好后也不会有测试提醒。选项 A:保持现状,另开任务修复 box 底图重建,先查明为何分析 pass 换阈值重试能成功而投影器不能(建议)。选项 B:恢复原断言并加 xfail(strict=True),需要用户对原计划第 2 节“不得加 xfail”破例。执行方不得自行选择。
  2. 深度图非零。 test_replay_wiring.py 把“深度恒为零”改为“有非零值”(实测 8926/133225)。需用户确认这段录像上 box 链路返回深度场是预期行为。

5. 不在本轮内

计时测试改为确定性测试,包括诊断实测 65.5 fps 高于假相机 30 fps 的原因:负载只会让测得帧率变低,这更像计数问题。另有:把 test_a_low_camera_rate_is_recorded_as_a_negotiation 中不依赖计时的断言拆回门禁;为 timing 测试提供单独的运行入口;autocal 测试树;Gitea runner。

交接记录

按 代理交接约定 维护;只保留当前状态和每轮一行摘要。

  • task_id:test-repair;round:3;updated_at:2026-10-18 21:20 +08:00
  • status:done;owner:Claude(验收);next_agent:无(第 4 节两项待用户决定后另开任务)
  • 目标与完成条件:第 3 节 R1–R4 的验收列全部满足,最终 gate.ps1 退出码 0
  • 范围:allowed_files 为 tools/gate.ps1、.githooks/pre-push、README.md(合并门禁一节)、 apps/studio/src/orisys_studio/replay_analysis.py、apps/studio/src/orisys_studio/replay_controller.py、 shared/src/orisys_app_shared/analysis/overlay_base.py、apps/studio/tests/ 下新增或修改的测试、 apps/studio/tests/data/README.md、本文件交接记录。排除:apps/autocal/**、orisys-sdk、 test_bare_video_analysis.py 的现有断言、放宽 tools/skip_budget.txt 或填写 tools/known_failures.txt、第 4 节两项
  • 停止条件:交接约定默认条件;需要改 orisys-sdk 或 apps/autocal 时停止并询问;时间预算 5 h
  • 影响面:overlay_base.py 属于 shared,当前唯一消费者是 replay_analysis.py;lint 默认基准改变后,推送前检查覆盖全部未推送提交
  • 授权:用户 2026-10-18 19:46 要求“写成给 DeepSeek 的后续任务”;执行需用户在 DeepSeek 会话中发出启动指令;不暂存、不提交、不推送

基准与输入

仓库/checkout 分支、HEAD 起始暂存/未暂存/未跟踪变化 本轮修改
D:\orisys_ws\orisys-app main;起点 fbf8c76(= 433b76e + 提交本文件);执行期间外部任务又提交 9352d0c、cf3e638、0998009,收尾 0998009 暂存区空;起点时 apps/autocal/** 7 个文件未暂存(另一任务),另有未跟踪的 apps/studio/tests/test_status_presenter.py 与 docs/architecture/studio-window-refactor-plan.zh.md;LZ.* 压缩包与目录未跟踪 8 个文件,见下表

本轮修改(SHA256 为收尾实测值,供写入核对):

文件 字节 SHA256
tools/gate.ps1 16266 a588d9d4cc5d80b90e06697efa48bd8bc3321843bb7ed8f99ca36bab0f29ab51
README.md 7426 7e9b36b014890f50a63c9391c8e6fcea0942f282e0cab3bd2a593d158569bd4f
shared/src/orisys_app_shared/analysis/overlay_base.py 9853 8b55059dbf0a65dcf015084605a2540d699af9b207f7f5d70cbc84fc0080a943
apps/studio/src/orisys_studio/replay_analysis.py 30003 aac7d47eab1301f4b8142497a3faa34c20b354e1aa069a4eeb0e7b327bb556a2
apps/studio/src/orisys_studio/replay_controller.py 76930 15155468465e11b5516b94de5c7271f5c44aa8ae8cc263233035f847c7305ae8
apps/studio/tests/test_overlay_failure_scope.py(新增) 5291 e1166c925b2203a5e13d3626fcaa7e255a000e9040d4878e9cfdddc96e252ac7
apps/studio/tests/test_replay_wiring.py 35799 ee2a315be57d75c4f26395691e7f0b8b83f593730edc3721002f16cfd7e11e2d
apps/studio/tests/data/README.md 2897 166cb831d1c0aa89f8c0c140eb3725127296af6fe334a5807c36695ac53bce85
本文件交接记录 — 随本记录变化,不列自哈希

.githooks/pre-push 未改:它调用 gate.ps1 时不传 -LintBase,默认值 origin/main 正是推送前需要的基准。

  • 环境:D:\orisys_ws\orisys-app\.venv-build\Scripts\python.exe,Windows PowerShell 5.1(powershell.exe)
  • 输入:apps/studio/tests/data/box_short_20260930/,实测 git diff 433b76e -- apps/studio/tests/data 为空;5 个文件 SHA256 已写进 apps/studio/tests/data/README.md

执行结果

验收项与预期 实际命令及 run_id 实际结果 证据路径
R1① -LintBase HEAD~1 的 lint.log 列出 433b76e 改过的 .py gate.ps1 -Task test-repair/round3 -LintBase HEAD~1(gate-20261018T121600Z) 通过:lint.log 新增 files checked against HEAD~1 (15),含 replay_controller.py、replay_analysis.py,退出码 0 round3/gate-20261018T121600Z/lint.log、summary.md
R1① 追加:范围覆盖已提交改动(用稳定基准排除“工作区脏”混淆) gate.ps1 -LintBase dcabd54(= 433b76e~1,gate-20261018T122730Z) 结果见“剩余限制”:lint 代码部分 no findings,29 个文件;该次失败是并行的外部文档改动触发文档门禁 round3/gate-20261018T122730Z/lint.log
R1② 无效基准退出码 2 gate.ps1 -LintBase no-such-ref 通过:gate: -LintBase 'no-such-ref' is not a valid git ref…,EXIT=2,未创建运行目录 本记录
R1③ 默认运行退出码 0 gate.ps1 -Task test-repair/round3(gate-20261018T130919Z) 通过:PASS,LintBase origin/main,33 个文件,exit 0 round3/gate-20261018T130919Z/summary.md
R2① finger 单帧失败不粘性 pytest apps/studio/tests/test_overlay_failure_scope.py 通过 6 项;第 2 轮代码上 2 项失败(assert True is False,overlay_unavailable 变 True) round3/r2-green.log、round3/r2-round2-fails.log
R2② box 失败一次即粘性且不再调用投影;③ 打开失败同 ② 同上 通过(calls == 1) 同上
R3①–④ 采纳 box 结果只设一次视图、只渲染一次、无拒绝文案、手选仍拒绝 pytest apps/studio/tests/test_replay_wiring.py -k adopting_a_box_result 通过;第 2 轮代码上失败 adoption rendered the frame 2 times, not once round3/r3-1.log、round3/r3-round2-fails.log
R3 输入不变 pytest apps/studio/tests/test_bare_video_analysis.py(随套件) 通过,未改其断言 round3/gate-20261018T130919Z/studio-suite.log
R4a 来源、dist 说明、5 个 SHA256 实测 Get-FileHash 与 .scratch/result-visible/recording/20260930T015028Z_session0002_…/ 逐字节一致 通过:5 个哈希已写入文件 apps/studio/tests/data/README.md
R4b UTC 运行号 + finally 删除 .active 多次 gate 运行(成功与失败各若干次) 通过:目录名 gate-20261018T130919Z 对应 UTC 13:09(本地 21:09);每次结束后 .scratch/test-repair/round3/.active 不存在 各 gate-* 目录
R4c ui_check.py 退出码非 0 判失败 临时让 ui_check.py 在打印干净汇总后 SystemExit(3),运行 gate(gate-20261018T125009Z) 通过:`ui_check failed
R4d 只放行 0xC0000005 ① 临时 hook 让套件以 -1073741819 结束(gate-20261018T125009Z);② PYTEST_ADDOPTS=-p exitprobe 让 shared 套件在干净 JUnit 后 os._exit(3)(gate-20261018T130308Z) 均通过:① `studio suite passed
  • 已完成:R1–R4 全部实现;临时场景用的 apps/studio/tools/ui_check.py、apps/studio/tests/conftest.py 已从 scratch 副本恢复,git diff --stat 对这两个文件为空;.scratch/test-repair/round3/exitprobe.py 只在受控运行中通过 PYTEST_ADDOPTS 加载,不是仓库文件。
  • 失败样本:第 2 轮代码上的两处红证据(R2 的 r2-round2-fails.log、R3 的 r3-round2-fails.log)保留在 scratch。
  • 剩余限制:① 执行期间有并行任务在本仓库提交(9352d0c、cf3e638、0998009)并短暂留下未提交的 studio 改动,gate-20261018T122730Z 的 lint 行因此判失败——那一行是文档门禁报出外部改动里的文档问题,代码部分是 no findings;同时暴露 lint_gate.py/ui_check.py 在 cp1252 控制台打印非 ASCII finding 会抛 UnicodeEncodeError(两处都在本任务 allowed_files 之外,未改)。② 最终验收运行前确认工作区只剩本任务 8 个改动。③ origin/main 落后于本地 9+ 提交,默认基准覆盖全部未推送提交。
  • 后台进程及 scratch 使用状态:无后台进程残留;.scratch/test-repair/.active 与 round3/.active 均不存在;round3/ 保留 8 次 gate 运行目录与运行日志。

验收与下一步

  • 轮次摘要:第 1 轮定义计划;第 2 轮交付 433b76e,验收判返工(见第 1 节);第 3 轮 DeepSeek 完成 R1–R4,用户提交为 c37efd7,验收接受(done)
  • 验收者、时间及复核时的代码/输入身份:Claude,2026-10-18 21:35 +08:00,HEAD c37efd7;上表 8 个文件及录像 5 个文件的 SHA256 与实测一致
  • 独立检查与结果:读了 c37efd7 的实际差异,R1–R4 与第 3 节一致;核对了 round3/gate-20261018T130919Z 的 JUnit 和两份第 2 轮红证据,与自报一致,哈希证明它们对应现在的代码。验收方没有可输入的 Windows 终端,门禁由用户独立运行:gate.ps1 -Task test-repair/accept -LintBase 0998009(accept/gate-20261018T132615Z)PASS,lint 5 个文件无 findings,studio 569 项、shared 485 项 0 失败 0 错误,ui_check 632 检查 0 失败,运行后无 .active 残留。不阻塞的意见见 .scratch/test-repair/round3-accept/review.md
  • 决定:接受;R1–R4 的验收列全部满足,最终门禁退出码 0
  • 下一步:第 4 节两项由用户决定;不阻塞意见可并入后续任务