资讯详情

用AI解决UI自动化三大耦合难题:从Playwright到Midscene.js

📅 2026/10/21 5:30:17 | 华诺云谱 👁 阅读
用AI解决UI自动化三大耦合难题:从Playwright到Midscene.js
这不是一篇技术对比评测更像是我在过去一段时间里从“用 Playwright 写脚本然后被前端版本迭代反复折腾”的状态逐步切换到“用 Midscene.js 让 AI 自己看懂页面”之后的一些真切体会。如果你正在维护一套 UI 自动化用例并且被那些“明明什么都没改跑一次就挂一次”的用例折磨到怀疑人生这篇内容应该能给你一些新的思路。标题里提到的“3大耦合难题”说白了就是传统 UI 测试脚本最脆弱的三个地方选择器与页面结构过度纠缠、操作时序与网络状态深度绑死、断言结果与业务数据强依赖。这三样东西组合在一起就变成了自动化测试最头疼的那句话“昨天还好好的今天全红了。”下面把这三件事拆开揉碎结合 Midscene.js 和 Playwright 的实测情况聊一聊 AI 是怎么破局的以及在真正落到工程里的时候又会遇到哪些新的麻烦。1. 传统 UI 测试的耦合困境是怎么一步步逼疯人的1.1 为什么脚本越写越脆跑得越久越不想碰传统 UI 自动化里Playwright 已经是做得相当出色的那一档了。它提供了 auto-waiting、actionability 检查、trace viewer、内置断言轮询这些能力比早期的 Selenium 要成熟非常多。但不管工具怎么帮你擦屁股只要你的脚本逻辑本质上还是在做三件事——找元素、等元素、校验元素——那就永远逃不开页面实现细节在你脚本里留下的一堆“钩子”。我举一个特别常见的场景你写了一条用例验证用户登录之后头像昵称显示正确。await page.goto(/dashboard); await expect(page.locator(.user-card .user-name)).toHaveText(某开发者);这条脚本在写出来的那一周里跑得很稳。但第二周前端改版把.user-card改成了.profile-wrapper昵称的 DOM 结构从span变成了div>await page.locator(.login-button).click();你只需要告诉它我要干什么await agent.ui.action(点击页面右上角的登录按钮);底层模型视觉语言模型直接“看”页面截图理解哪儿是登录按钮然后把点击动作自动映射到真实坐标或元素句柄上。这一个转变直接把“结构耦合”从根上卸掉了。因为你的测试操作不再依赖.class-name或[data-testid]这种实现细节你写的是“用户操作”不是“DOM 操作”。2.2 语义层面的可读性也把项目沟通成本压下来了一个很直观的体验是Midscene.js 的用例写出来产品经理、前端开发、测试同事大家看的都是同一份描述不再需要翻译层。传统 Playwright 的用例本质上是一串 API 调用。它表达的是“执行了什么操作”但很难表达“为什么要这样做”。而用 Midscene.js 写的步骤几乎就是一本可读性极强的操作手册。这在实际团队协作里价值非常大尤其是需求变更之后回头梳理测试覆盖范围的成本比过去低得多。当然Midscene.js 并不是要替代 Playwright 这种基础设施。恰恰相反它的实现本身就建立在 Playwright 之上。这一点后面细说。2.3 规划与执行分离这个设计非常关键Midscene.js 的架构里模型层负责“规划”Playwright 负责“执行”。AI 不是直接去输出一串控制浏览器的底层命令那样分分钟跑飞而是先理解页面、规划出动作序列再交给确定性代码去做实际点击、输入和断言。这个设计的妙处在于AI 只承担“理解”这一步凡是能靠确定性逻辑解决的点击坐标、键盘输入、滚动、等待全部交给 Playwright 底层完成。用大白话说就是AI 负责“看”和“想”Playwright 负责“手”。这种互相配合的组合确保了整个执行链路不会因为模型的随机性而失控。这也是为什么 Midscene.js 看着“自由”但实际跑起来还是稳的底层原因。3. 用 Midscene.js 解开传统三大耦合难题的实战拆解3.1 第一刀解决选择器与页面结构的耦合这个是最明显、也是见效最快的一项。Playwright 时代你面对改版只能拼命加>await agent.ui.action(等待“数据刷新完成”提示出现然后点击页面右侧的“导出报表”按钮);整条指令里没有 sleep没有 waitForRsponse完全靠 AI 判断页面状态是否就绪。实测下来这个思路在页面状态判定上比手动写等待信号要稳定得多。3.3 第三刀解决断言与业务数据的耦合第三刀也是最微妙的一刀因为这里的“松紧”取舍最难。传统断言写死数据数据一变测试就崩写得太松测试又变成了“我验证了元素存在”。Midscene.js 的断言走的是自然语言描述。你可以这样写const result await agent.ui.assert(页面上是否显示了今天的订单总金额且金额大于 0); if (!result) { // 业务异常可上报 }AI 直接理解“今天的订单总金额大于 0”这个语义不需要你知道 DOM 里是哪一行、哪个 span 对应这个值。如果业务规则改成了以“元”为单位显示比如从 12.00 变成了 12.05你不用去改断言目标最多改一下描述里的业务口径即可。但这里我必须说句实话AI 断言适合业务语义的“真伪判断”不适合高精度的数值计算校验。比如需要验证“折扣后的实际支付金额 原价 × 0.85 - 优惠券金额”这是一个确定性极高的数学逻辑用 AI 断言反而是多余且容易出错的。这种情况下你应该继续用 Playwright 的确定性断言或者直接用接口层的自动化来做。我的建议是分层处理。**页面结构类校验、状态类判断、交互类反馈交给 AI数值计算类、数据一致性类交给确定性代码。**两者结合才是一个完整且稳定的自动化方案。这里我把三种场景做了一个对比场景类型传统 Playwright 体验Midscene.js 体验页面改版、结构变化选择器失效用例全红需逐个修复无需修改AI 按视觉语义重新定位异步渲染、接口抖动靠 waitFor偶尔 flaky需要排查日志依据页面整体状态决策抗抖动性更强业务数据变化断言硬编码数据一变即挂自然语言描述业务语义维护成本低这三个场景你只要项目中碰到过其中一个并且被反复折腾过就能理解为什么我把这三点称为传统 UI 测试的核心痛点。改写一个>npm i midscene接下来你用它的 agent 接入方式跑一次最简单的 demo就能快速感知到从“结构驱动”到“意图驱动”的核心差异。比如这样一段脚本import { Agent } from midscene; // 实例化 agent底层默认会驱动浏览器执行 const agent new Agent({ target: https://example.com/login, }); await agent.ui.action(输入用户名 demo_user); await agent.ui.action(输入密码 123456); await agent.ui.action(点击登录按钮); const loginResult await agent.ui.assert(登录成功页面右上角出现仪表盘入口);执行前不需要给任何元素加id或>import { chromium } from playwright; const browser await chromium.launch(); const page await browser.newPage(); await page.goto(https://example.com/app); // 传统确定性操作填表校验输入框行为 await page.fill(#user-account-input, demo_user); await expect(page.locator(#user-account-input)).toHaveValue(demo_user); // Midscene.js 语义操作处理仪器盘区域的复杂交互 const midsceneAgent new Agent({ page }); await midsceneAgent.ui.action(切换视图到“周趋势”); await midsceneAgent.ui.assert(图表标题显示为“周趋势”且右侧出现导出按钮);这种混搭方式既保留了 Playwright 在稳定场景里的高效率也获得了 AI 在动态、复杂场景里的灵活性。这也是我在实际项目里跑下来最舒服、最踏实的落地模式。4.4 团队分工与脚本维护方式脚本从结构驱动切换到语义驱动之后分工模式也要跟着调整。以前改一个选择器往往要等熟悉前端细节的同事来定位现在用自然语言描述测试人员自己就能完成大部分维护工作。“面向业务描述写脚本、面向视觉语义做维护”这个模式让团队成员之间的协作关系变得更平滑重点也从“抠 DOM 结构”转向了“梳理业务流程”。5. 常见问题排查与结合实际的心得5.1 AI 识别成功率不稳定怎么办我不止一次遇到有人问AI 跑脚本是不是有时候找不准元素确实存在这种情况。我的经验是**AI 的识别成功率跟页面元素的视觉显著性正相关。**页面里的主按钮、大标题、明确的输入框识别率极高但那种只有 12 号灰字、藏在一个角落里的小链接就非常容易识别失败。这类问题的解法在自然语言指令中补充更多上下文明确位置或相关元素比如“点击表格第一行右侧的操作菜单按钮”如果元素本身视觉辨识度太低可以用 Playwright 的选择器直接做兜底保持页面关键操作的视觉层级清晰这对 AI 自动化本身就是一种正向促进。5.2 运行性能会比纯 Playwright 慢吗这个问题的答案取决于“慢”的定义。单纯从点击一个按钮的角度看AI 识别比直接locator.click()多了一步“看懂页面”的开销。涉及模型推理的话单步耗时从几百毫秒到几秒不等。对于大量稳定、重复、高并发的回归场景纯 Playwright 的性能优势依然明显。但你把一个真实项目的“总维护时间”摊开来看AI 节省的时间是远超那几十毫秒的单步耗时的。一条脚本从开发到维护到稳定运行的完整生命周期里AI 省掉的部分往往是按天计的。所以我的判断是性能不是核心瓶颈稳定性和维护成本才是。5.3 对页面权限、登录态等基础能力的影响Midscene.js 依赖真实浏览器环境来运行登录态、Cookie、本地存储这些能力都是通过底层 Playwright 的 context 去管理的所以不存在“用 AI 之后登录态就变成黑盒”的问题。你甚至可以在登录之后手动保存 storage state 供后续用例复用这部分逻辑和传统 Playwright 完全一致。5.4 一些产品层面的小思考Midscene.js 最大的产品价值不是帮你“少写代码”而是帮你**“少维护代码”**。我在一个跨季度项目里深有体会前两个月拼命写 Playwright 用例第三个月开始不断修选择器和调试 flaky 用例换成 Midscene.js 之后脚本量的实际书写时间没有明显降低但脚本全绿维持的时间显著拉长了。这种“稳”的体验做测试的同学应该都能理解。写在最后我个人的建议是不要急着把 Playwright 替换掉更不要觉得用了 Midscene.js 之后所有测试问题都能解决。真正高效的做法是把两者的能力拼在一起——确定性交给底层工具灵活性交给 AI 语义层。这就像两个配合默契的同事一个负责执行力一个负责理解力合在一起比任何单打独斗都要稳得多。如果你现在正在被选择器飘红、用例时好时坏、断言维护想骂人的问题困扰我给的建议非常直接打开 Midscene.js 的仓库挑一个你最头疼的页面写一个“点击 断言”的 demo 跑一跑。花半天时间你就能感受到从“问 DOM”到“问页面”的体验转变。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑