为测试修复加入第 3 轮返工任务

验收 433b76e 时发现门禁不 lint 已提交改动、叠加底图失败范围过大且回退无测试,故定义返工项。文档门禁 clean。
This commit is contained in:
ykcheungab
2026-10-18 20:04:26 +08:00
parent 433b76e43c
commit fbf8c76bb5
2 changed files with 84 additions and 41 deletions
+2 -41
View File
@@ -1,6 +1,6 @@
# Studio / shared 测试修复与门禁计划 # Studio / shared 测试修复与门禁计划
状态:待实施。日期:2026-10-18。基线:`orisys-app` `main` 的 `85d0b39`。执行者:一个代理(DeepSeek),按顺序完成, 状态:阶段 0–6 已交付(`433b76e`),返工见 [第 3 轮返工](test-repair-rework.zh.md)。日期:2026-10-18。基线:`orisys-app` `main` 的 `85d0b39`。执行者:一个代理(DeepSeek),按顺序完成,
每个阶段结束时向用户汇报。本计划补充 [分层测试执行计划](test-execution-plan.zh.md),不替代它。 每个阶段结束时向用户汇报。本计划补充 [分层测试执行计划](test-execution-plan.zh.md),不替代它。
## 1. 为什么要做 ## 1. 为什么要做
@@ -75,43 +75,4 @@
## 交接记录 ## 交接记录
按 [代理交接约定](../../docs/platform/agent-handoff.zh.md) 维护;只保留当前状态和每轮一行摘要。 自第 3 轮起移至 [第 3 轮返工](test-repair-rework.zh.md),本文件不再维护任务状态。第 2 轮的完整记录见 `433b76e` 中的本文件。
- task_id:test-repair;round:2;updated_at:2026-10-18 18:45 +08:00
- status:ready(待验收);owner:Claude(定义);executed_by:DeepSeek
- 目标与完成条件:用户 18:36 把范围扩到全计划,阶段 0–6 全部执行,验收以第 4 节各行与本记录为准
- 范围:`pyproject.toml`、`apps/studio/**`(tests、tools、locales、docs)、`shared/tests/**`、新增
`tools/gate.ps1` 等门禁文件;`apps/autocal/**` 一律未改
- 停止条件:交接约定的默认条件;收集问题必须改 autocal 文件时停止(未触发)
- 时间预算:按第 4 节估时逐阶段累计;等待用户决定与数据的时间不计
- 影响面:根 `pyproject.toml` 的 `--strict-markers` 同时作用于 autocal 测试树;收集已核对(0 未知标记、
0 错误)
- 授权:用户 18:36 授权执行全计划并按阶段汇报;本轮未提交、未推送、未安装依赖
### 基准与输入
| 仓库/checkout | 分支、HEAD | 起始暂存/未暂存/未跟踪变化 | 本轮修改 |
|---|---|---|---|
| `D:\orisys_ws\orisys-app` | `main`、`e268a9d`(执行期间他人提交到 `9a3886b`,均属 autocal 任务) | autocal 有其他任务的改动(已由其自行提交),不属本任务 | 23 项修好、门禁落地、录像入库;见下 |
- 环境:`D:\orisys_ws\orisys-app\.venv-build\Scripts\python.exe`(版本见 phase0 汇总)
- 输入:录像从 `.scratch/result-visible/` 找回(帧号 20…52,与测试期望一致),复制进
`apps/studio/tests/data/box_short_20260930/`(3.79 MB,不含 preroll);用户无需补录
### 执行结果
| 验收项与预期 | 实际命令及 run_id | 实际结果 | 证据路径 |
|---|---|---|---|
| 阶段 0:失败清单与第 3 节对上 | 两次全量 pytest + `ui_check.py` | 23 项逐项对上;另有 ui_check 重试竞态 | `.scratch/test-repair/phase0/` |
| 阶段 1:根目录收集 0 错误;`timing` 排除 | `python -m pytest --collect-only` | 112 文件 1754 项、0 错误;排除 3 项 | `phase1/` |
| 阶段 2:数据用例可运行 | 三个数据用例文件 | 12 / 11 / 30 项全绿 | `phase2/` |
| 阶段 3:3–10 号 | 定向用例 | 全绿;9、10 号按用户决定 | `phase3/items*.xml` |
| 阶段 4:门禁 | `tools/gate.ps1` | 当前状态退出码 0;改坏断言、删数据均非 0 | `.scratch/gate/gate-*` |
| 阶段 5:钩子与文档 | `git config core.hooksPath .githooks`(未安装) | README 与两份计划已改;文档门禁 clean | `scripts/doc_lint.py` |
### 验收与下一步
- 轮次摘要:阶段 0–6 完成;偏差(`timing` 三项、box 叠加画布、四处计划外过时断言)见
`.scratch/test-repair/final-report.md`
- 验收者:用户(或评审代理);决定:待验收
- 下一步:box 画布重建与计时确定性各开任务;等用户授权后再提交
+82
View File
@@ -0,0 +1,82 @@
# Studio 测试修复:第 3 轮返工
状态:rework。日期:2026-10-18。前序计划与诊断:[测试修复与门禁计划](test-repair-plan.zh.md),其阶段 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。
## 交接记录
按 [代理交接约定](../../docs/platform/agent-handoff.zh.md) 维护;只保留当前状态和每轮一行摘要。
- task_id:test-repair;round:3;updated_at:2026-10-18 19:55 +08:00
- status:rework;owner:Claude(定义与验收);next_agent:DeepSeek(执行)
- 目标与完成条件:第 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`、`433b76e`,领先 `origin/main` 8 个提交 | 暂存区空;`apps/autocal/**` 7 个文件未暂存,属另一任务;根目录 `LZ.*` 压缩包与目录未跟踪,非本任务;本文件及原计划交接记录的定义改动待用户提交 | 执行方填写文件清单及 SHA256 |
- 环境:`D:\orisys_ws\orisys-app\.venv-build\Scripts\python.exe`,Windows PowerShell 5.1
- 输入:`apps/studio/tests/data/box_short_20260930/`,须与 `433b76e` 一致(`git diff 433b76e -- apps/studio/tests/data` 为空)
### 执行结果
| 验收项与预期 | 实际命令及 run_id | 实际结果 | 证据路径 |
|---|---|---|---|
| R1–R4,见第 3 节 | 执行方填写 | 未执行 | `.scratch/test-repair/round3/` |
- 已完成、失败样本、剩余限制:
- 后台进程及 scratch 使用状态:
### 验收与下一步
- 轮次摘要:第 1 轮定义计划;第 2 轮 DeepSeek 完成阶段 0–6,提交为 `433b76e`,报告在 `.scratch/test-repair/final-report.md`,完整记录见该提交中的原计划;第 3 轮验收判返工,原因见第 1 节
- 验收者、时间及复核时的代码/输入身份:Claude,2026-10-18 19:40 +08:00,`433b76e`
- 独立检查与结果:只读审查 38 个文件的实际差异,以及 `lint_gate.py`、`overlay_base.py` 的相关代码。**未独立复跑** `gate.ps1` 与两套测试,因为验收方当时只有 Linux shell,没有该 Windows 解释器;第 2 轮自报的测试数字仍属未验证,第 3 轮验收时复跑
- 决定:返工;依据原计划第 4 节阶段 4(门禁须检查改动文件)与第 2 节(不扩大到 box 以外的行为变化)
- 下一步:用户提交本文件后,在 DeepSeek 会话中发出启动指令;完成后标 review,交回 Claude 验收