AI测试 AI 生成的自动化脚本,怎么才能让人敢放进 CI:聊聊定位器与复合组件的几个坑

w471176877 · September 29, 2026 · 136 hits

背景:一个很诱人的演示,和一个很脆弱的工程

让带浏览器控制的 AI agent 直接跑 E2E,演示阶段通常很惊艳:一句话,它把登录、下单、断言都点完了。但拿到日常回归里,问题会集中爆发在三处:

  • 不可复现:两次执行路径不同、定位方式不同,失败原因无法归因;
  • 成本:用例越多、频次越高,token 账单越难看;
  • 无法评审:产物是"agent 的一段执行历史",你没法 Code Review,也没法 diff。

我这半年在做的一件事,就是把这条链路切开:生成交给模型,回放交回 Playwright。生成过程用自然语言描述流程,模型先给步骤计划,确认后在真实浏览器里逐步执行,每个动作成功即解析成结构化的语义定位器步骤落库;之后回放完全由 Playwright 确定性执行,不调用模型。项目开源在 TestDog(MIT),下面写的是实现过程中真正踩过的几个坑——这些坑跟用不用 AI 其实关系不大,都是 Web 自动化的老问题。

坑一:复合组件上的"假成功"

这是我认为最容易被自动化框架忽略的问题。

Ant Design / Element / Vant 的下拉、树选择、级联、日期、时间、滑块,不是原生 <select>。常见的写法是 click 触发器 → click 选项,代码看着执行完了、DOM 也变了,但表单内部状态没有提交。脚本报绿,业务没生效。

TesterHome 的同学对这种问题应该不陌生,社区里讨论过不少"元素点了没反应"的案例,本质是动作成功 ≠ 业务终态达成。

我的处理办法是按组件库拆成语义动作插件(下拉 / 树选 / 级联 / 日期 / 时间 / 滑块),覆盖 Ant Design、Element(element-ui 与 element-plus)、Vant、MUI;原生 <select> 走 selectOption 兜底。每个动作遵循三态结果协议(成功 / 失败 / 待定),返回前在页内做后验校验确认终态生效,才算这一步成功。宁可返回"待定",也不要返回一个假的成功。

坑二:定位器优先级,决定了脚本能活多久

我的实践优先级是:语义(role + 可访问名)> 文本 / label / placeholder > 结构(CSS / 相对路径)。

几个具体结论:

  • 坐标点击 / 视觉点击适合生成,不适合回放。生成期让多模态模型看截图辅助理解是有效的;回放期依赖坐标,字体、缩放、视口一变就是随机失败。
  • 同名元素必须显式指定作用域。"确定"按钮在弹窗和页面上各一个,用父容器限定比用索引 nth 靠谱。
  • 步骤要人能看懂。落库的步骤是 {action, target:{strategy,role,name}, fallbacks, scope, assertions} 这种结构,界面上能逐条改、能加断言、能导出——能评审的脚本,才有人敢改。

坑三:定位器失效时,要不要"自动自愈"

很多工具把自愈做成了静默能力:定位器挂了,模型换个选择器,自动回写,脚本继续跑。我不太敢这么用,理由是静默改变测试的定位方式,等于悄悄降低测试的确定性——某天脚本绿了,但它其实已经不再校验你原来关心的那个元素。

我的做法是:自愈只在失败时触发,模型提出替代定位器后,由人确认是否回写原脚本;不确认就保持失败,让人去看证据(失败截图 + console + network)。

这一条也许有争议,很希望听听社区的看法:自愈应该自动回写,还是必须人工确认?

一个具体的工程细节

顺带说一个跟平台无关的坑,也是最近修的(v0.1.7):Windows 上 Hyper-V / WSL2 / Docker 会随机保留一段 TCP 端口,桌面端如果固定用 4123 做后端端口,恰好落在保留段内就起不来,界面上只看到 Failed to fetch。现在改成启动时从 4123 起向后探测可用端口,后端启动失败时把原因和日志路径直接弹出来。把"ghost 失败"变成"有原因可查的失败",这件事在测试工具里优先级很高。

现状与限制

利益相关:我是 TestDog 的作者,本文写的是自己的实现与踩坑,不构成第三方评测。

No Reply at the moment.
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up。