前端

Odoo 前端为什么不只靠截图回归:web_tour、Hoot 与非确定性检查讲透

Odoo 的前端回归保护不是单一测试框架,而是把交互步骤、自动化执行、记录器和 Hoot 运行时拼成一整套机制。更关键的是,官方还专门检查 trigger 的非确定性,避免“今天过、明天挂”的脆弱测试。

前端
进阶 开发者 2 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

很多团队做前端回归,最后都会陷入两个极端:

  • 要么只做单元测试,覆盖不到真实交互链路;
  • 要么只做端到端点点点,脚本又脆得像玻璃。

Odoo 的有意思之处在于,它没有把“前端测试”押宝在单一工具上,而是把几层东西拼在了一起:

  • web_tour 描述用户步骤;
  • tour_service 管注册、校验与运行入口;
  • 自动/交互模式分别承担不同用途;
  • Hoot 提供底层测试运行和 DOM 辅助;
  • recorder 还能反向帮你生成步骤草稿。

更重要的是,Odoo 明确把一个大问题拉到了台面上:

测试脚本能跑,不代表它稳定;真正麻烦的是选择器和触发条件的非确定性。

这也是它比“随便写个 E2E 脚本”更成熟的地方。

一、web_tour 的核心价值是用“步骤”描述用户意图,而不是只写点击脚本

addons/web_tour/static/src/js/tour_step.js 能看到,一个 step 至少包含:

  • trigger
  • 可选 run
  • 可选 timeout
  • 以及对外展示的内容说明

这背后的心智模型很清楚:

  • 先定义在什么 UI 条件下这一步算可执行;
  • 再决定执行什么动作。

这和很多脆弱自动化脚本的差异很大。后者往往一上来就“找元素然后点”,忽略了“为什么现在应该点它”。

Odoo 把 trigger 作为第一公民,本质上是在强调:测试不是回放鼠标,而是在验证界面是否进入了正确状态

二、tour_service 把 tour 当成可注册、可校验的运行时能力

tour_service.js 里会给 web_tour.tours registry 加 schema validation,还统一提供启动入口。

这意味着一个 tour 不是随便 export 一个数组,而是:

  • 有明确结构;
  • 可以被 registry 管理;
  • 可以被 debug 菜单与测试运行时发现;
  • 运行前先过合法性检查。

这种服务化设计有很大好处:

  • 大量 tour 共存时不容易失控;
  • 不同 addon 可以自然扩展;
  • 调试入口、自动执行入口、记录器都能挂在同一生态上。

三、自动模式与交互模式,其实解决的是不同问题

tour_automatictour_interactive 不是“同一个东西两个皮肤”。

自动模式

更像 CI 里的回归守门员:

  • 发现 trigger;
  • 自动执行 run;
  • 超时则失败;
  • 在日志里输出步骤上下文。

交互模式

更像引导与调试工具:

  • 把当前步骤指给人看;
  • 允许人工按提示完成;
  • 适合 onboarding、功能演示、手动排障。

这两者共用 step 模型,却服务不同场景,正是 Odoo tour 体系强大的地方。

四、最值得夸的是:官方正面处理“非确定性 trigger”

tour_step_automatic.js 和相关测试,会发现 Odoo 专门检查 Potential non deterministic behavior

这件事非常重要,因为前端自动化最隐蔽、最耗人的 bug 不是“语法错”,而是:

  • 选择器有时候匹配 A,有时候匹配 B;
  • 动画和异步渲染让目标一闪而过;
  • modal、overlay、hidden/visible 状态把步骤搞得时好时坏;
  • 某些元素在不同 DOM 时序下都可能满足 trigger。

很多团队遇到这种 flaky test,只会不断加:

  • sleep
  • retry
  • 更长 timeout

结果只是把问题藏起来。

Odoo 的态度更对:先怀疑 trigger 是否本身不确定。

这是一种非常难得的测试工程意识。

五、Hoot 让 tour 不只是“浏览器黑盒点击”

web 模块里能看到 Hoot 相关 loader、mock 和 DOM 工具;在 web_tour 里还能看到 tour_helpers_hoot.js

这说明 Odoo 的前端测试栈并不是:

  • 一个 tour 系统;
  • 外加另一个毫无关系的测试框架。

相反,Hoot 充当的是低层执行与辅助能力,帮助:

  • 选择器查询;
  • 时间推进;
  • 事件模拟;
  • DOM 断言;
  • 更可控的自动步骤执行。

换句话说,tour 给出“用户过程模型”,Hoot 提供“更可控的执行地基”。

六、tour recorder 的价值不是替代思考,而是降低起稿成本

tour_recorder.js 会记录点击、输入、拖拽,并尝试生成较短选择器。

这很实用,但也很容易被误解。

Recorder 最有价值的地方,不是“自动生成一份完美 tour”,而是:

  • 帮你把真实操作转成初稿;
  • 暴露出当前页面选择器是否难以稳定表达;
  • 让测试作者从空白页起步时少走很多路。

真正可靠的 tour 仍然需要人工判断:

  • trigger 是否稳定;
  • 文本匹配是否过脆;
  • run 动作是否太依赖时序。

七、为什么这套体系比截图回归更适合 Odoo

截图回归当然有用,但它擅长的是:

  • 布局变化;
  • 样式缺失;
  • 明显视觉偏移。

而 Odoo 大量前端问题属于另一类:

  • 按钮现在能不能点;
  • 搜索面板步骤有没有真正生效;
  • modal 前后层级是否正确;
  • 一次业务流程的交互链是否还能走通。

这些问题单靠截图很难判断。tour 则更接近“用户任务是否还能完成”。

所以对 ERP 而言,基于步骤与状态的回归保护通常比纯视觉比较更有性价比。

八、二开团队最该吸收的不是工具名,而是方法论

读完这套源码,最值得带走的是三个方法论:

1)先描述状态,再描述动作

一个好 step 先说明“什么时候该做”,而不是急着 click。

2)对 flaky test,不先加 sleep,先查 trigger 稳不稳

这是 Odoo 最成熟的一点。

3)让工具链互相配合

  • tour 提供业务流程层;
  • Hoot 提供执行与断言层;
  • recorder 提供起稿层;
  • service/registry 提供组织层。

这比“找一个万能测试框架包打天下”更现实。

九、总结:Odoo 的回归保护,重点不是自动化,而是可重复性

真正好的前端回归系统,目标从来不只是“自动跑起来”,而是同样的用户路径每次都能被可靠地重演

Odoo 用 web_tour + Hoot + determinism checks + recorder 做到的,就是把“可重复性”作为第一优先级。

这也是为什么它的测试体系值得前端团队认真借鉴:

  • 它不迷信单元测试万能;
  • 也不迷信端到端脚本越多越好;
  • 它关心的,是步骤是否明确、触发条件是否稳定、执行环境是否可控。

说到底,能长期保护复杂 Web Client 的,不是测试数量,而是测试是否真的可重复、可解释、可维护

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。