确定性判定 + LLM 裁判:Hover Cloud 如何评估一次测试运行
一次测试运行只告诉你 pass 还是 fail,但这不是真正要紧的问题。要紧的是:这次失败到底意味着什么——是 UI 挪了位置、测试要换个 selector,是应用真的坏了,还是有人改了句文案、把断言熬旧了?红叉答不上来。人读日志答得上来,但慢,一次只能盯一个失败。
Hover Cloud 分两层来回答。第一层是确定性的,把大部分活干掉;第二层是一个 LLM 裁判,只接手第一层判不了的情况。两层分开,正是整套设计的精髓。
第 1 层:确定性断言评估
判定的大部分来自事实,而非判断。事实有四类:
- 状态(status)——这次运行里,spec 是通过、失败还是 flaky。
- 记录(record)——这条 spec 在最近若干次运行、若干分支上的表现。一条在 mainline 上就已经红的 spec,不是你这个 PR 的锅。
- 覆盖(coverage)——套件到底演练了哪些业务线,读自你 repo 提交的
.hover/hover-map.md。 - 确定性(determinism)——这条 spec 在通过与失败之间翻转得有多频繁。一条 flaky 的 spec,和一次真回归,是两个不同的问题。
有了这些,Hover 用纯代码、零 AI 就能算出判定:
- Heal Queue 按错误的形态给每个失败分类。action 步骤的 locator 再也解析不到,是 drift(改测试)。应用挂了、返回 500、页面崩溃,是 bug(改应用,这条 spec 就是现成的复现)。断言执行到了却没通过,是 unclear——因为单从这里看,改文案和真回归长得一模一样。
- 每条失败的 spec,会在 PR 上拿到一个 merge-confidence 判定:
pre-existing、flaky、regression或unknown。这判定要靠单个 CI job 永远看不到的跨运行、跨分支历史,而 Cloud 手里正好有。每个判定都附着它的 reason,可供你审计。
这一层不碰任何模型。它便宜,可精确复现,也能把判定的理由讲清楚。它守的是绿色路径,因此绝不能寄望于某个模型"今天状态正好"。
第 2 层:LLM 裁判
到了 unclear 这一桶,以及任何没有唯一正解的问题上,确定性就到头了。"文案改完之后,这个页面做的还对吗?"——没有哪条断言能一锤定音。这时候就该裁判上场了。
有一条规矩让它不越界:AI 只作用于已经跑过的东西。 裁判从不碰绿色构建,也从不写代码。它读一遍已经发生的失败,对照这条流程当初记下的意图,给它打分,而不是投 pass/fail。眼下 Hover 用模型把 PR 失败摘要写得像一位细心的同事写出来的那样,底下的判定照旧来自第 1 层。裁判的下一份活儿就是 unclear 队列:为"一个变了的结果还符不符合意图"打分,好让需要人过目的失败更少。
LLM 当裁判,长于读懂意图,短于充当真理之源。所以让它打分,而不让它裁定那些确定性的事实。放到别处,你就得为每次绿色运行掏 token,还得白白背上自己没写进去的波动。
会复利的资产
每 crystallize 一条流程,你就把一条 happy path 存成了普通 Playwright。坚持一阵,套件便从一件杂活熬成一项资产:一张守着你已上线系统的回归网。你发得越多,产品里被"在 CI 里免费跑的测试"钉住的部分就越多,上面那两层也就越能精准地判断:一次新改动有没有弄坏原本好端端的东西。
这正是 AI 生成代码里安静的那一面:代码来得比谁都读得快,所以唯一撑得住的防线,是一张不断变大、写起来很便宜、跑起来不花钱的检查网。
闭环:定义业务,而不是写代码
把这两层顺着推到底,结论就是:你不再手写代码,也不再手点应用。取而代之,当你做一个功能时,你的 Claude Code(或任何 MCP agent)会跑起这样一个闭环:
- 从一条清晰的业务规则定义出发,先设计回归测试。
- 生成代码。
- 推上去,CI 把整套测试当作纯 Playwright 跑一遍。
- Hover 的两层返回一个判定:drift 就自愈、bug 就标记、unclear 就打分。
- 反复迭代,直到本地代码和回归测试对上。
人的工作往上挪了一层。你不写断言,也不写实现,只定义什么该为真。瓶颈落到了模型唯一替不了你的那件事上:把你的业务到底该做什么说清楚。Hover 把这份定义放在它该在的地方——随代码一起提交的业务图与记住的规则里,这样闭环手边永远有一份意图 spec 可以对照。
目前进展到哪
确定性这一层已经上线:drift/bug/unclear 分类器、merge-confidence、PR 上的业务覆盖,还有 flakiness 打分,如今都在跑,作用于你自己 CI 产出的运行。LLM 裁判目前负责把 PR 摘要写出来;给 unclear 队列打分、闭合完整的"先写回归"闭环,是它接下来的去向。这个先后是刻意的:先把确定性内核做得可信,再只在真正没有标准答案的地方引入判断。
在你自己的应用上试试 Hover。
把 Hover 的 MCP 加到你已经在用的编码 agent。它探索你的应用,结晶出你自己拥有的纯 Playwright spec。
npm i -g @hover-dev/mcp && claude mcp add hover -- hover-mcp阅读快速开始 →