news 2026/9/28 20:29:59

Expect Watch模式工作原理深度剖析:代码变更如何智能触发浏览器回归测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Expect Watch模式工作原理深度剖析:代码变更如何智能触发浏览器回归测试

Expect Watch模式工作原理深度剖析:代码变更如何智能触发浏览器回归测试

【免费下载链接】expectExpect tests your agent's code in a real browser项目地址: https://gitcode.com/gh_mirrors/expect6/expect

Expect 是一个让 AI 编程智能体在真实浏览器中自动回归测试你代码的开源工具。它的Watch 模式是关键亮点:终端里挂起一个监控循环,自动捕获 git 代码变更,由 AI 评估这些改动是否影响用户可见行为,再智能地触发一次真实浏览器回归测试。本文基于源码深度剖析 Expect Watch 模式的工作原理,讲清楚代码变更是如何被捕捉、过滤、评估并最终触发测试的。

什么是 Expect Watch 模式:一个不下班的"浏览器测试哨兵"

Expect 的核心思路是:读取你的 git 变更 → 生成测试计划 → 用 Playwright 驱动真实浏览器执行,覆盖性能(LCP、INP)、安全、设计细节(悬停态、死链)和应用完整性检查。

而Watch 模式把"跑一次"升级为"常驻监控":你在开发循环中持续改动代码,Expect 负责判断哪些改动值得测试,并在该测的时候自动开测。入口命令很简单(源码:apps/cli/src/commands/watch.ts):

  • expect watch:默认监控changes(相对 main 分支的全部差异)
  • -t, --target:可切换为unstaged(未暂存改动)或branch(分支差异)
  • -m, --message:自定义自然语言测试指令,默认是"在浏览器中测试 main 的所有变更并确认它们正确工作"
  • -a, --agent:指定评估/执行用的智能体(Claude Code、Codex 等),自动检测本机已装智能体

核心机制全景图:轮询 → 稳定化 → 智能评估 → 执行

整个 Watch 循环由 packages/supervisor/src/watch.ts 中的Watch服务驱动,是一条由事件串联的流水线。源码中定义了完整的WatchEvent事件族:Polling → ChangeDetected → Settling → Assessing → RunStarting → RunUpdate → RunCompleted(以及Skipped/Error/Stopped),每一步都有明确的状态。

第一步:每 2 秒为仓库"计算指纹"

轮询间隔为2000ms(常量WATCH_POLL_INTERVAL_MS)。每次轮询不是盲目地"看文件有没有变",而是调用computeFingerprint计算一个仓库指纹:

  • 指纹 =SHA-256(HEAD 提交 + 未暂存 diff + 已暂存 diff),实现见 git/git.ts
  • 若指纹与"上一次测试过的指纹"相同 → 只发一个Polling事件,什么都不做
  • 若不同 → 发出ChangeDetected,进入下一关

指纹机制让"有没有变化"的判断是 O(1) 的字符串比较,无需扫描文件树。

第二步:3 秒"稳定化窗口",拒绝测试半成品

检测到变更后,Watch 并不立刻行动,而是进入Settling 阶段等待 3000ms(WATCH_SETTLE_DELAY_MS),然后重新计算指纹:

  • 指纹没变 → 说明改动已落盘稳定,继续流水线
  • 指纹变了 → 说明你还在继续改(典型的"边打字边保存"场景),本轮直接放弃,等待下一轮轮询覆盖新状态

这个小而精的设计避免了对"半截保存"的代码跑测试,也天然实现了变更防抖(debounce):你连改三次,只有停下来 3 秒后才会触发一次测试。

第三步:双层决策——确定性过滤 + AI 评估

这是 Watch 模式"智能"的核心。决策分两层,先便宜后昂贵:

第一层:确定性分类(零成本)

classifyDeterministically(watch.ts)会检查本次变更的所有文件是否都命中"无需测试"清单:

类型示例
文档/纯文本.md、.txt、.mdx
配置样板.prettierrc、.eslintignore、.editorconfig
锁文件package-lock.json、*.lock、lock.yaml
工具目录.github/(copilot 除外)、.husky/、.vscode/、.cursor/、.idea/
其他LICENSE、CHANGELOG、.env.example

只要全部变更文件都命中,直接skip——连 AI 都不调用。

第二层:AI 分类(只处理真正模糊的改动)

对剩下的改动,Watch 会构建一个专门的分类提示词(buildWatchAssessmentPrompt,prompts.ts),把变更文件列表 + diff 预览 + 你的测试指令交给智能体,要求它只回答一个单词:

  • run— 改动影响用户可见行为(UI、路由、API 调用、样式、文案、影响运行时行为的配置)
  • skip— 纯内部改动(注释、纯类型重构、仅测试文件、文档、锁文件、CI 配置)

提示词里写死了两条关键规则:拿不准就 run、不要解释理由。响应解析函数parseAssessmentResponse对大小写、空白、前缀宽容(" Run "也能识别),其完整边界用例见单元测试 watch.test.ts。

第四步:交给执行器跑真实浏览器回归

一旦决策为run,Watch 把上下文交给Executor(packages/supervisor/src/executor.ts):智能体生成测试计划,Playwright 驱动真实浏览器(可选注入你系统浏览器的真实 cookie,模拟已登录用户)逐步执行。执行过程中RunUpdate事件持续把步骤状态推给界面;全部完成后:

  1. 发出RunCompleted,终端更新运行次数与通过/失败结果,并可选择系统通知提醒(sendWatchNotification)
  2. **保存"已测试指纹"**到项目的.expect状态目录(该目录自带.gitignore,见 git/git.ts)——下次轮询时指纹不变就绝不会再重复测试,避免浪费

容错设计:背压回退与"宁多测,勿漏测"

Watch 的失败哲学是安全失败(fail-safe):误触发一次测试只是浪费几分钟,而漏测才是真风险。

  • 评估失败计数:AI 返回了无法解析的内容时,失败计数 +1;同一个指纹下连续失败达到2 次(ASSESSMENT_BACKOFF_LIMIT)后,放弃调用 AI,直接默认run,避免反复烧 token
  • 智能体异常兜底:流中断、会话创建失败、未登录、用量超限等所有 agent 错误(handleAgentAssessmentError)一律降级为run并记录警告日志
  • 执行错误不中断循环:单次执行出错只发Error事件,轮询循环继续,等下一轮变更

事件驱动的终端界面:你看到的是什么

CLI 侧的 Watch 界面(watch-screen.tsx)是一个纯事件消费者:把WatchEvent映射为六种 UI 阶段(polling / settling / assessing / running / idle / error),并维护运行计数、最近结果(passed/failed)与耗时计时。也就是说,你在终端看到的每次"转圈",背后都精确对应上述流水线中的某一个阶段。

快速上手:三步开启 Watch 模式

  1. 确认环境:处于一个 git 仓库内(非仓库目录会回退为按当前目录工作)
  2. 启动监控:运行expect watch,可选加上-m "重点检查登录流程"或-t unstaged
  3. 安心开发:改代码 → 停手 3 秒 → 自动评估 → 该测就测;指纹没变则永不重复测试

常用参数(见 README.md 的 Options 表):-a <agent>指定智能体、--browser-mode headless无头运行、-u <url>直接指定开发服务器地址。

关键源码路径速查

模块路径职责
Watch 主循环packages/supervisor/src/watch.ts轮询、稳定化、双层决策、背压
指纹与 git 状态packages/supervisor/src/git/git.tsSHA-256 指纹、已测试指纹持久化
分类提示词packages/shared/src/prompts.tsrun/skip 单字决策提示词
浏览器执行器packages/supervisor/src/executor.ts测试计划生成与 Playwright 执行
CLI 命令入口apps/cli/src/commands/watch.ts参数解析与界面挂载
终端 Watch 界面apps/cli/src/components/screens/watch-screen.tsx事件 → 阶段映射、通知

一句话总结:Expect Watch 模式 =2 秒指纹轮询 + 3 秒稳定化防抖 + 确定性过滤与 AI 分类的双层决策 + 真实浏览器回归执行,并用"宁多测、勿漏测"的容错策略保证监控永不失手。

【免费下载链接】expectExpect tests your agent's code in a real browser项目地址: https://gitcode.com/gh_mirrors/expect6/expect

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

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

6G显存跑27B大模型:三进制量化与ninfer引擎实战解析

先说我第一次看到“6G显存跑27B大模型”这种说法时的反应&#xff1a;八成又是标题党。27B参数放在一年多前&#xff0c;光权重就得几十G显存&#xff0c;再怎么量化也得14G以上才敢说“能跑”。就算现在量化方案成熟了&#xff0c;6G显卡连7B的fp16模型都装得勉强&#xff0c;…

作者头像 李华
网站建设 2026/9/28 20:29:23

Codex配置避坑指南:从config.toml到一键部署与DeepSeek接入

1. 从"配置地狱"到"一键起飞"&#xff1a;Codex助手部署的真实痛点如果你最近在折腾 Codex 这类 AI 编码助手&#xff0c;大概率经历过这样的场景&#xff1a;兴冲冲地装完 CLI&#xff0c;敲下第一条命令&#xff0c;结果终端甩回来一句codex auth token …

作者头像 李华
网站建设 2026/9/28 20:29:13

高并发写入场景下的消息队列异步处理实践

1. 背景 在互联网业务高速发展的今天&#xff0c;高并发写入已成为系统设计的常态。无论是用户行为日志、订单创建、评论发布还是 IoT 设备上报&#xff0c;都会在短时间内产生海量写入请求。随着业务规模扩张&#xff0c;系统面临的写入压力持续攀升&#xff0c;如何在高并发下…

作者头像 李华
网站建设 2026/9/28 20:28:55

千问 8R 立减券申领通道,外卖打车都能用

安装千问这个软件&#xff08;未用过&#xff09;&#xff0c;然后打开对话输入字符口令&#xff08;9月实测稳定&#xff09;&#xff1a;新用户福利100012&#xff0c;操作方法如下&#xff1a;即可轻松领取&#xff01;小伙伴们可以抓紧去试一试吧~~

作者头像 李华