news 2026/9/10 15:20:30

Actual Budget Bug 修复 PR 浏览器验证手册:edge 复现 + 预览环境确认的闭环流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Actual Budget Bug 修复 PR 浏览器验证手册:edge 复现 + 预览环境确认的闭环流程

Actual Budget Bug 修复 PR 浏览器验证手册:edge 复现 + 预览环境确认的闭环流程

【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual

导读

本文基于 Actual Budget 仓库中 review-actual-pr 技能 的配套测试手册,系统讲解如何对bug 修复类 Pull Request进行可验证的浏览器测试。核心方法是双环境证据闭环:先在线上构建edge.actualbudget.org上复现 bug,再在 PR 对应的 Netlify 预览环境中用同一套步骤确认修复生效,最终用真值表给出明确结论。读完本文,你将掌握从 PR 推导复现计划、使用playwright-cli驱动浏览器取证、处理预览环境失效与 demo 数据不足等边界情况,以及在代码审查报告中规范陈述测试结论的完整实战方案。


为什么 bug 修复 PR 需要"双份证据"

对于 bug 类 PR,测试阶段必须产出两类证据,缺一不可:

  • 修复前 bug 确实存在:在edge.actualbudget.org(线上 edge 构建)上按 PR 描述复现问题;
  • 修复后 bug 不再出现:在 PR 的 Netlify 预览构建上执行同样的复现步骤,确认行为已改变。

原手册对此给出了两个非常犀利的理由:

一个"看起来正确"但实际不改变运行时行为的修复,是潜在的回归隐患;一个在 edge 上根本复现不出来的 bug,说明修复可能是在解决一个"幽灵问题"。

也就是说,只看代码 diff 无法证明修复真实有效;只复现 bug 也无法证明修复已生效。两者互为印证,才能让测试结论具备证据力。

这一思路与仓库中 AGENTS.md 所倡导的"减少 mock、优先真实实现"的测试哲学一脉相承——浏览器测试尽可能在真实构建、真实数据上运行,而不是在理想化的测试桩里自说自话。

工作流总览与关键常量

整套流程分为四步:推导复现计划 → edge 复现 → 预览验证 → 结论判定。测试前先固定三个常量:

常量说明
EDGE_URLhttps://edge.actualbudget.org/线上 edge 构建,代表当前主干代码的实际运行行为
PREVIEW_URLhttps://deploy-preview-<num>.demo.actualbudget.org/PR 对应的 Netlify 预览,<num>替换为 PR 编号
输出目录~/Downloads/pr-review-<num>/一次评审的所有截图、元数据、diff 与报告集中存放

输出目录与 SKILL.md 中的工作目录约定一致:一次完整的 PR 评审会在这个目录下沉淀pr.jsongh pr view元数据)、diff.patchgh pr diff)、review.md(评审报告)、before-edge.pngafter-preview.png(bug PR 的成对证据截图),以及可选的findings.json结构化发现。

Step 1 — 从 PR 推导复现计划

测试的第一步不是打开浏览器,而是先回答一个问题:"这个 bug 到底怎么触发?"

从 PR 的标题、正文以及关联 issue 中,整理出一份有序、具体的操作步骤列表。原手册给出的示例值得借鉴:

打开 Reports → 点击 Cash Flow → 设置日期范围为上月 → 预期出现图表,实际观察到空白画布。

对比一下"具体"与"模糊"的差别:

  • ❌ 模糊:"检查现金流水报表是否正常"
  • ✅ 具体:"打开报表 → 点击现金流水 → 设置日期范围为上月 → 预期图表,观察空白画布"

步骤必须具体到可以在真实 UI 中逐步执行。如果 PR 正文提供的信息不足以推导出复现路径,则需要抓取关联 issue 的正文:

# 从 "Fixes #1234" / "Closes #1234" 中提取 issue 编号 ISSUE_NUM=... gh issue view $ISSUE_NUM --repo actualbudget/actual --json title,body,labels

硬性红线:读完整理完关联 issue 后仍然无法得出清晰的复现步骤,必须停止测试阶段并告知用户,绝不凭空编造一个复现路径。这条"禁止伪造复现"的规则是整套技能的最高优先级约束之一,理由很简单——部分证据比没有证据更糟糕,一个编造的复现会让整个评审结论失真。

Step 2 — 在 edge 上复现 bug

确定复现计划后,先在线上 edge 构建上打开应用:

playwright-cli open $EDGE_URL playwright-cli snapshot

playwright-cli是本仓库评审流程依赖的浏览器自动化命令行工具:open打开指定 URL,snapshot输出当前 DOM 的可访问性快照(包含元素角色、名称与可点击性),后续所有点击都以快照中的引用(ref)为依据。

标准 demo 设置

首次进入应用会看到设置(onboarding)界面。按 AGENTS.md 中 "Testing and previewing the app" 一节的约定,执行标准 demo 初始化:

  1. 点击"Don't use a server"(不连接同步服务器);
  2. 点击"View demo"(加载演示预算)。

等待预算加载完成后,再逐步骤执行复现计划。

为什么选择 demo 预算而不是空预算?从源码看,createDemoBudget会以testMode: true的方式创建一个名为 "Demo Budget" 的测试预算(packages/loot-core/src/server/budgetfiles/app.ts),它预置了真实的账户、交易、分类和预算金额数据,远比空白预算适合验证报表、交易列表等需要数据支撑的功能路径。该 demo 预算的固定 ID 为_demo-budget,并且是多标签页 coordinator 中特殊对待的"可驱逐"预算组(参见 coordinator.ts 对create-demo-budget消息与_demo-budget组驱逐的处理),保证重复创建 demo 不会堆积残留状态。仓库 E2E 测试中同样依赖 demo 数据(如 onboarding.test.ts 加载ynab4-demo-budget.zipactual-demo-budget.zip等演示数据文件),可见 demo 预置数据是项目测试基础设施的一等公民。

逐步骤取证

复现计划要一步一快照地推进:每执行一步点击后重新snapshot,确保下一步点击使用的是新鲜的 DOM 引用(页面状态变化后旧 ref 会失效)。当走到失败状态时,立即截图存证:

playwright-cli screenshot --filename=$HOME/Downloads/pr-review-<num>/before-edge.png

在运行摘要中如实记录:bug 是否按描述复现了?

  • 复现成功:继续 Step 3。
  • 未复现:这是一个重要发现,必须在报告中如实说明并停止。可能的原因是该修复属于防御性改动,针对的是一条难以触达的路径——这种情况下应把观察到的现象升级给用户判断,而不是硬凑结论。
  • demo 数据不足以支撑复现(例如 bug 需要多币种环境而 demo 是单币种的):同样明确说明并停止,绝不伪造。

Step 3 — 在预览环境验证修复

关闭 edge 页面,切换到 PR 的 Netlify 预览:

playwright-cli close playwright-cli open $PREVIEW_URL playwright-cli snapshot

预览环境未就绪的处理

如果页面返回 404 或 "site not found",等待约 10 秒后重载一次即可——Netlify 部署有时会滞后于 GitHub PR 事件。若重试后仍然打不开:

  • 停止测试
  • 在报告中说明预览 URL 无法加载;
  • 代码审查照常交付(只是不含测试章节)。

绝不降级去测试一个过期构建——那会让"修复是否生效"的证据完全失效。

重复验证流程

预览加载成功后,重复同样的标准 demo 设置同样的复现步骤(注意两个环境的 demo 数据是一致的,因此复现结果可以直接对比,这一点在 SKILL.md 的标准 demo 设置一节有明确说明),然后截图:

playwright-cli screenshot --filename=$HOME/Downloads/pr-review-<num>/after-preview.png

此时你手上就有了成对的证据:before-edge.png(修复前 bug 存在)与after-preview.png(修复后 bug 消失)。

Step 4 — 判定结论:四象限真值表

在报告(SKILL.md 中定义了完整的报告结构,含 Testing 章节)中,用三行直白的陈述收尾:

  • Bug reproduces on edge: yes / no
  • Bug reproduces on preview: yes / no
  • Verdict: fix confirmed | fix not observable | repro inconclusive

判定逻辑由真值表决定:

EdgePreview结论
yesnofix confirmed(修复已确认)
yesyesfix not observable(修复不可观察)—— 升级处理
nonorepro inconclusive(复现无定论)—— 说明原因
noyesregression(回归)—— PR 把问题改得更糟了

对每种结局的理解:

  • yes → no(修复确认):最理想的结果,edge 上出 bug、预览上不出,双份证据齐备,修复真实改变了运行时行为。
  • yes → yes(修复不可观察):bug 在两个环境都复现,说明修复在真实运行时并未生效——即使代码看起来"改对了",也要升级处理,这正是"看起来正确但没改变运行时行为"的那类风险。
  • no → no(复现无定论):两个环境都复现不出,必须说明为什么(demo 数据不够?需要特定前置条件?),不能含糊带过。
  • no → yes(回归):罕见但极其重要。edge 上没问题的行为在预览上反而出问题,说明 PR 引入了回归。一旦触发此情况,必须在代码审查章节同步标记为 Critical。

"回归"象限的存在正是双环境对比的价值所在:单环境测试永远无法发现"修复方案把原本正常的行为改坏了"这类问题。

测试实践的三个关键注意事项

1. 视觉类 bug 必须统一视口

如果 bug 属于视觉问题(布局、颜色、对齐),两个 URL 都要用相同的视口尺寸

playwright-cli resize 1280 800

在每次 demo 设置前执行。否则两个环境默认视口尺寸不一致,可能掩盖或伪造出差异,导致误判。feature PR 手册(browser-testing-feature.md)同样强调设置一个可呈现的视口(如 1440×900),可见视口一致性是浏览器测试取证的基础纪律。

2. demo 数据可能不够用,要如实说明

交易列表、报表类 bug 常常依赖足够规模的数据才能暴露。demo 预置数据规模有限,如果怀疑"数据量不够所以没复现",要明确说出来——不要用"看起来没问题"这种话搪塞,因为那意味着你实际上并未真正走通代码路径。这类"数据不足导致复现不充分"的情况,对应真值表中的repro inconclusive,必须说明原因。

3. 流程边界:何时该停,何时该继续

整个手册贯穿一条决策主线——何时必须停止

场景动作
无法从 PR 和 issue 推导出复现计划停止测试,告知用户
bug 在 edge 上未复现(可能为防御性修复)报告现象,停止并升级
demo 数据不支持复现所需环境说明并停止,不伪造
预览 URL 重试后仍不可用停止测试,报告 URL 问题,代码审查照常交付
视觉类 bug 未统一视口重新设置视口后再测

"停止并升级"不是消极逃避,而是对证据质量的负责——这条规则与 SKILL.md 的硬性规定(绝不伪造复现、绝不向 GitHub 回写任何评论)共同构成整套评审技能的可信度基石。

与仓库测试基础设施的衔接

这套浏览器验证流程并非孤立存在,它与仓库既有的测试体系深度衔接:

  • E2E 测试:仓库在packages/desktop-client/e2e/下用 Playwright 编写了覆盖账户、预算、报表、规则、日程等功能的端到端测试(本地运行方式见 AGENTS.md:yarn workspace @actual-app/web e2e),其中的页面模型(如 configuration-page.ts 通过 "Try the demo" 按钮创建 demo 文件)与手册中的 demo 设置流程一一对应;
  • 视觉回归测试(VRT)yarn vrt/yarn vrt:docker负责快照级的 UI 回归比对,快照存放在各测试文件的*-snapshots/目录下,可作为视觉类 bug 的补充证据手段;
  • feature PR 流程:本文面向 bug PR;对于功能/增强型 PR,走的是另一套只测预览、带红色虚线高亮标注截图的流程(参见 browser-testing-feature.md 与标注脚本 highlight-element.js),两套手册共同覆盖了 PR 评审的浏览器测试环节。

总结

Actual Budget 的 bug 修复 PR 浏览器验证流程,本质上是一套以双环境对比为核心的证据闭环

  1. 从 PR/issue 推导出可执行的复现计划(不可伪造);
  2. 在 edge 上确认 bug 真实存在(before-edge.png);
  3. 在 Netlify 预览上确认修复生效(after-preview.png);
  4. 用四象限真值表给出明确结论,并对regression象限保持最高警惕。

这套流程的可贵之处在于它把"测试"从模糊的"看看行不行"变成了可复现、可取证、可判定的人工验收协议,并且为每一类失败场景都预设了明确的停止条件——既保证了评审质量,也保护了证据的真实性。对于任何需要验证"修复是否真的修好了"的 PR 评审场景,这套方法都值得直接复用。

【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 15:16:46

STM32单片机指纹门禁系统稳定性设计与实战

简介&#xff1a;这是一份面向嵌入式初学者与单片机课程设计者的指纹门禁系统实战源码&#xff0c;基于STM32F10x系列单片机实现完整生物识别门禁功能&#xff0c;解决身份验证、权限管理与电控执行等核心问题。资源共103个文件&#xff0c;以32个C源文件&#xff08;含stm32f1…

作者头像 李华
网站建设 2026/9/10 15:16:38

UniApp Android 开机自启动:无原生插件离线打包方案

做 Android 一体机、广告机、门禁面板这类“桌面应用”的兄弟应该都有同感&#xff1a;设备一通电&#xff0c;系统启动完成&#xff0c;应用就得自己出现在桌面上&#xff0c;这是硬需求。用户不管你是不是 UniApp 写的&#xff0c;也不会体贴你“要不要先点一下图标”。一旦落…

作者头像 李华
网站建设 2026/9/10 15:16:09

风光储协同发电系统Simulink建模与优化控制策略

1. 项目背景与核心价值 风光储协同发电系统作为新能源领域的黄金组合&#xff0c;正在全球范围内掀起一场能源革命。这个Simulink模型研究项目直指行业痛点——如何实现风机、光伏与储能的有机配合。我去年参与某200MW风光互补电站调试时&#xff0c;就曾因各子系统协调控制问题…

作者头像 李华
网站建设 2026/9/10 15:15:57

微信聊天记录导出完整指南:十分钟拿到永久HTML存档

微信聊天记录导出完整指南&#xff1a;十分钟拿到永久HTML存档 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMs…

作者头像 李华