我做UI自动化这些年最怕的不是写脚本而是改版。某次给一套后台管理系统做回归开发把登录按钮的class从btn-primary改成了base-button结果二十多条用例一夜之间全红。你去找原因发现不是业务逻辑错了而是选择器失效了。这种事干多了真的会怀疑人生。后来我接触了Midscene.js这类AI视觉自动化测试工具用自然语言去驱动测试很多过去周期性爆发的“修选择器”问题才开始真正降下来。Midscene.js简单说就是一套开源的、用大模型视觉能力驱动UI自动化的框架。你不需要再写一堆#id .class或XPath只要像跟人说话一样告诉它“点击右上角的登录按钮”“在搜索框输入关键词”它会自己看页面截图定位元素然后控制浏览器去执行。这篇文章不适合拿来做纯广告我直接讲我实际使用的过程和踩过的坑尽量让你在几分钟内跑通第一遍并且理解它为什么能用、怎么用才不容易翻车。1. 为什么我会盯上Midscene.js传统UI自动化的痛它真的能治先说说传统UI自动化最折磨人的几个点不然你没法理解我为什么会对一个“让AI点鼠标”的工具这么上头。第一选择器太脆弱。UI自动化的根基是元素定位但前端代码是个活物今天div明天span今天加个v-if明天换个渲染时机。你用CSS选择器、XPath去定位本质上是在跟前端实现细节绑死。绑死的结果就是前端一次重构测试基建跟着碎一地。第二复杂场景表达成本高。想验证“用户登录后能看到订单列表里的第一条记录”用传统脚本你要先写等待元素可见再拿文本再写断言步骤又多又容易踩时序问题。要是遇到Canvas、WebGL、视频播放器这类无法用DOM定位的场景传统方案基本抓瞎。第三维护成本占比太高。业内一个常说但不爱听的真相是自动化测试的维护成本可以占到总成本的60%以上。团队忙活半天做的不是业务验证而是给前端“补选择器的坑”。Midscene.js的解题思路很直接让AI直接看界面用自然语言代替定位表达式。它把页面截图交给多模态大模型模型理解你的指令返回目标坐标和操作类型再由工具调用浏览器真实执行。说白了就是给自动化脚本装了一双眼睛和一个会听人话的大脑。它能做什么举几个我常用的场景输入内容、点击按钮、滚动页面、拖拽元素、提取页面数据、做视觉断言、生成测试报告。它支持YAML这种低代码方式也支持TypeScript/JavaScript SDK方式还能在浏览器里直接打开可视化调试界面看着AI一步步操作。适合谁来参考如果你是Web测试工程师手上有大量回归任务被选择器折磨过如果你在做RPA类似的流程自动化想用更接近自然语言的方式写脚本如果你对AI Agent感兴趣想研究大模型怎么跟浏览器结合又或者你维护着一个老项目测试覆盖率约等于零想低成本补一层冒烟测试那Midscene.js是目前我试过的一批方案里最值得拿来上手的一个。2. 5分钟入门实操从零跑通第一个AI视觉脚本标题说“5分钟掌握”说实话有点夸张但跑通第一个脚本5分钟真够。我拆成四个步骤你一步步来。2.1 准备环境Node、浏览器模型API这工具基于Node生态所以第一步是把环境准备好。我的本机是Windows系统装了Node.js 20 LTSnpm随Node一起带。如果你电脑上还没Node去官网下载LTS版装上命令行里输node -v能看到版本号就行。浏览器方面它底层通过Playwright驱动浏览器所以本地得有可用的浏览器。Midscene.js在首次运行时会自动处理浏览器内核的安装你只要保证系统有Chrome或Edge就行。我用的是Chrome稳定版没做过特殊配置。然后是最关键的一步准备一个支持视觉理解的大模型API。因为整套工具的核心是把截图发给模型去识别所以这个API一定要有多模态能力。你手上如果有现成的、能用视觉模型的API Key直接填进去就行。没有的话找任意一个国内能访问且提供视觉模型接口的服务商注册后拿个API Key大多数都有免费额度或极低价格的内测额度够你玩很久。我提醒一句不要用纯文本模型去跑除非你真能看到“小明”这种文本模型认真瞎蒙截图的样子。用错模型定位成功率会断崖式下降。2.2 最简安装一条命令装两个包在空目录里初始化项目然后安装SDK和命令行工具。mkdir midscene-demo cd midscene-demo npm init -y npm install -D midscene/web midscene/cli装完你可以在package.json里看到这两个依赖。顺手加一个环境变量文件把API Key和模型名写进去避免每次敲命令都带参数。# 在项目根目录新建 .env 文件 MIDSCENE_MODEL你的模型名 MIDSCENE_API_KEY你的API Key注意具体环境变量名不同版本可能稍有调整以你安装版本自带文档为准。但思路都一样让工具知道该调哪个模型服务、用什么密钥。2.3 用YAML写第一个用例我个人非常推荐新手从YAML模式切入原因是它足够直观不需要懂编程。在项目里建一个login.yaml内容大概长这样url: https://example.com steps: - ai: 在用户名输入框输入 admin - ai: 在密码输入框输入 123456 - ai: 点击登录按钮 - ai: 断言页面出现欢迎回来文字然后运行npx midscene run login.yaml工具会自动打开浏览器按步骤执行。跑完会在目录下生成一份带截图的报告你点开就能看到AI每一步做了什么、看到了什么、点了哪里。这一个流程就足够你建立基本体感了。2.4 用SDK写一个TS脚本如果你需要更复杂的控制比如登录后复用会话、循环遍历列表、调外部接口那就得上SDK。它的核心对象是Agent你通过它来指挥浏览器。下面是我最早跑通的示例结构和实际场景一致import { Agent } from midscene/web; const agent new Agent({ model: 你的视觉模型名, apiKey: 你的API Key, cache: true, // 开启缓存重复输入会快一点 headless: false, // 有头模式方便观察 }); async function main() { await agent.openPage(https://example.com); await agent.ai(在用户名输入框输入 admin); await agent.ai(在密码输入框输入 123456); await agent.ai(点击登录按钮); await agent.ai(等待页面出现欢迎回来文字); await agent.ai(点击订单列表菜单); const result await agent.aiQuery(当前页面上第一个订单的单号是什么); console.log(订单号:, result.text); await agent.close(); } main();ai方法负责操作aiQuery负责从页面提取信息返回结果可以直接拿来写断言。这个脚本跑通之后你基本就摸到Midscene.js的门了。2.5 在可视化界面里“手把手”调教它如果你想知道AI到底会怎么理解你的话最有效的办法是用它的可视化调试界面。在浏览器里打开目标页面输入类似“点击右上角的用户头像”这种指令它会展示模型返回的坐标框以及它准备执行什么动作。这个方式对调试自然语言指令极其有用。很多时候脚本跑不过不是工具不行而是你描述得太模糊比如只说“点那个按钮”AI确实分不清是哪一个。我把“5分钟”实际花在哪算给你听装包1分钟写Key 30秒写YAML或脚本2分钟跑通1到2分钟。要是卡住了多半卡在API没通或者描述太模糊后面我会专门讲怎么排查。3. 核心机制拆解AI到底是怎么定位元素的用自然语言操作浏览器听起来很神奇但底层拆开其实不复杂。理解这个流程能帮你在脚本写不顺时快速定位问题。3.1 整个识别链路Midscene.js的工作流大概是这样的打开页面后先对当前视口截图然后把你输入的自然语言指令连同这张截图一起发送给视觉大模型模型理解指令目标后返回一个结构化的结果比如“目标类型点击坐标x860, y540置信度0.92”工具根据这个结果驱动Playwright在浏览器里执行真实的鼠标点击、键盘输入等操作。这个过程很像你给一个第一次来办公室的实习生发微信截图“看到右上角那个人头图标没点一下。”他会先看图找到那个人头图标在照片里的大致位置然后伸手去点。AI视觉自动化就是把“实习生”换成“多模态大模型”。3.2 自然语言指令的“翻译”过程所谓“翻译”其实是模型在做两件事语义理解明白你想对什么元素做什么操作视觉定位在截图里找到那个元素并给出坐标。这两个能力都来自大模型的训练基础。所以指令质量直接决定定位质量。这是我和AI视觉类工具相处后最深的体会。你说“点击登录按钮”如果页面上只有一个登录按钮它不会搞错如果页面上既有“登录”又有“注册”而且长得像它可能就会犹豫结果也容易飘。这时候你需要多给一点上下文比如“点击表单下方红色背景的登录按钮”。另外Midscene.js不只支持“点击”“输入”像“悬停”“长按”“拖拽”“滚动”“等待出现”这些动作也能描述本质都是让模型理解你的意图然后落到浏览器操作上。特别是“等待接口数据加载后再操作”这类时序问题用自然语言写反而更符合人类直觉因为你不用学各种显式等待API。3.3 两种模式纯视觉模式与DOM辅助模式Midscene.js在实际使用中有偏重纯视觉识别的路线也有结合DOM结构辅助理解的路线。纯视觉模式就是前面说的“看图点坐标”好处是跨端一致性好不管你测试的是Web还是将来做移动端WebView它都不依赖具体的DOM实现缺点是模型成本稍高理解耗时也长一点。DOM辅助模式则会额外把页面的DOM结构、可访问性信息喂给模型让模型在理解上更容易命中。好处是定位更稳、更便宜缺点是又跟DOM绑了一点关系但绑得比选择器松多了。它至少不需要你维护那种一行改版就失效的脆弱表达式。我的建议是核心回归链路用DOM辅助模式追求稳定复杂视觉场景比如Canvas图表、视频画面用纯视觉模式去弥补传统方案的空缺。两者不是互斥关系而是配合使用的关系。3.4 为什么AI测试不会100%稳定这点我必须直说AI视觉自动化不是银弹它的稳定性做不到100%。原因也很朴素模型可能看错、页面可能没加载完、提示弹窗可能恰好挡住了目标元素、截图分辨率变化可能导致坐标偏移。这些都是物理世界的不确定性它没有消失只是从“选择器失效”换成了“AI看走眼”。但这不代表它不值得用。我实际体验下来一个写得很具体的AI用例成功率在九成以上配合重试机制和稳健断言跑到95%以上完全没问题。关键是你要知道它的脾性给它好的指令给它合理的等待时机它就能稳定工作。4. 从零到可用一个完整的登录列表页测试实操理论讲一堆不如跑一个完整场景。下面这个例子是我在某开源商城Demo上实操过的流程我简化了业务细节但保留了完整代码逻辑你可以直接拿去套自己的项目。4.1 场景设定目标站点是某商城后台泛称用本地Demo账号密码登录登录后进入订单列表需要从列表里提取第一条订单号并断言页面状态正常。4.2 YAML SDK混合方式的完整结构我会用SDK配合一个更细的步骤注释。因为SDK能处理登录会话、数据提取和循环比纯YAML更适合真实业务。import { Agent } from midscene/web; // 登录态缓存避免每次都重新登录 const authState { cookies: [], localStorage: [], }; async function login(agent: Agent) { await agent.openPage(https://your-demo-site.com/login); await agent.ai(在用户名输入框输入 admin); await agent.ai(在密码输入框输入 123456); await agent.ai(点击登录按钮); await agent.ai(等待页面右上角出现退出登录文字); } async function fetchFirstOrderId(agent: Agent) { await agent.openPage(https://your-demo-site.com/orders); await agent.ai(等待订单表格加载完成); // 提取第一条订单号 const result await agent.aiQuery( 当前订单表格第一行的订单号是什么只返回订单号数字即可 ); return result.text; } async function main() { const agent new Agent({ model: 你的视觉模型名, apiKey: 你的API Key, cache: true, headless: false, }); try { await login(agent); const orderId await fetchFirstOrderId(agent); console.log(拿到的订单号, orderId); // 断言 await agent.ai(断言页面包含订单号 ${orderId}); console.log(测试通过); } finally { await agent.close(); } } main();这个脚本里我特意加了两个关键点。一个是登录后马上做“等待出现退出登录”的确认用这个动作代替传统意义上的“等待元素可见”能大幅减少时序问题。另一个是用aiQuery把结果提取出来再拿变量去写断言。这样做的价值在于你不是只测一个静态页面而是在做真实的业务闭环验证。4.3 报告与调试看AI每一步的“思考过程”跑完脚本后Midscene.js会在输出目录生成报告文件里面包含每一步的截图、模型的返回内容、动作坐标、耗时等。我个人使用报告最多的时候是用例跑挂的时候。如果某一步AI没找到元素报告里会留下当时的页面截图和你发出的指令一眼就能看出是“页面还没加载出来”还是“AI点错了地方”。另外还有MHTML快照等于是把页面现场完整存下来。你可以事后在浏览器里打开快照回忆当时页面到底长什么样。这个功能做线上问题复现特别好用用户报了个bug你不用问他“当时页面长啥样”直接看快照就行。4.4 断言怎么写才不脆多模态模型做信息提取是强项但你如果让它做“精确到小数点后两位”的断言那是给自己找麻烦。我总结了一套写AI断言的节奏一是断言状态不要断言细节。比如“断言页面出现运营数据概览区域”比“断言某个数字等于1000”稳得多。二是能用文本提取就别让AI硬猜。先用aiQuery拿到数值再用本地断言比较。三是给断言加等待。页面数据是异步加载的直接断言很容易因为在数据回来前执行而失败。用一个“等待XX出现”的指令先垫一下成功率会高很多。这就像你让同事去会议室看看投影准备好没有他会先走过去、推开门、看一眼再回来告诉你结果。你要是跟他说“你量子远程观测一下投影状态”那是为难人。5. 实战中踩过的坑7条高频问题排查实录工具用久了总会遇到一些翻车现场。这里我整理了自己和同行交流后最常碰到的七类问题每条都带着解法。5.1 元素一直找不到怎么描述才准确最常见的失败原因是自然语言指令太模糊。页面上一堆按钮你说“点那个小按钮”AI也懵。对策有两个一是增加空间位置描述比如“右上角的”“表格上方的”“弹窗里的”二是增加外观特征描述比如“蓝色背景的”“带有购物车图标的”。还有一个非常实用的技巧如果页面有两个输入框一个用户名一个密码不要只写“输入admin”要写“在用户名输入框输入admin该输入框在密码框上方”语境一旦明确模型基本不会认错。5.2 API连不上、超时和调用失败这个问题出现频率极高。先分清是网络问题还是参数问题。如果是网络问题换一个当前环境可稳定访问的API端点如果是超时把工具的请求超时调大同时在脚本里加上重试机制。我自己写的时候会把对AI的调用包一层retry失败两次再整体报错而不是让它第一次失败就把用例挂掉。原理很简单模型服务偶尔抽风是正常现象重试就能过。5.3 登录后会话怎么保持浏览器自动化里最常见的麻烦是每次跑用例都重新登录一遍慢且容易触发风控。Midscene.js底层是Playwright所以它支持保存浏览器的存储状态。你可以先跑一次登录脚本把cookies和localStorage存到JSON文件里之后的用例直接加载这份状态从头跳到登录后的页面开始执行。这个做法能省下大量时间也让测试更稳定。5.4 iframe和跨域页面怎么处理iframe真的是UI自动化老手都会皱眉的东西。传统方案切frame切到怀疑人生Midscene.js当然也绕不开“iframe内的元素不在当前主文档里”这个事实但它的优势在于你可以在指令里带上清晰的上下文比如“点击右侧客服聊天框里的发送按钮”因为模型看到的是整张截图它知道发送按钮在哪个panel里。如果遇到元素死活不可点先试试指令里明确提到“在iframe内”或者“在右侧面板内”效果往往出奇地好。5.5 懒加载、动效和滚动问题很多页面的数据是滚动后才加载的。AI看不见视口以下的元素你让它点页面底部的按钮它只会截图当前视口自然找不到。解决方式也简单先加一个“滚动到页面底部”或“滚动到XX附近”的指令再执行后续操作。用自然语言写“滚动到订单列表区域”比用scrollIntoView写死位置更符合人的直觉。5.6 模型选型与成本控制不同的视觉模型在识别能力和价格上差别很大。我这里不方便点具体品牌但给你一条选择路径先用手头最强的视觉模型跑通逻辑再根据你的用例复杂度逐步换更轻量的模型。如果页面结构简单、目标元素固定便宜的模型完全够用如果页面信息密度高、元素长得像那就别省这个钱。成本方面开启缓存能显著减少重复请求因为同一个页面的截图在短时间内会被重复利用。场景推荐模型等级理由登录、表单、简单按钮轻量视觉模型结构固定识别难度低复杂后台、数据表格中端视觉模型需要理解表格语义Canvas、图表、视频画面高端视觉模型空间关系复杂大批量回归轻量模型重试控成本容忍少量重跑5.7 结果不稳定重试与多轮判定AI结果天生有概率性。面对这个现实我建议你在关键链路上加“二次确认”。比如第一步登录后用“等待出现退出登录文字”作为登录成功的凭据再继续往下走。在CI里跑的时候可以把易失败的用例设置成失败后自动重跑一次。用三次跑两次过的“多数投票法”去判断一个用例是否健康而不是追求单次必须过。这套思路和人工测试一样人也会偶尔点错连点两次都点错才算真有问题。6. AI视觉自动化的适用边界什么时候用它什么时候别用聊了这么多我得给你泼一盆冷静水。AI视觉自动化很强但不是所有场景都应该无脑上。6.1 我最推荐的三个场景第一跨端回归。同一套自然语言脚本跑Web页面和跑移动端H5页面逻辑基本可以复用因为你描述的是业务动作而不是DOM结构。第二复杂视觉断言。Canvas图表、视频播放状态、地图区域渲染传统选择器拿不到数据但AI能看一眼图就知道“地图上出现了三个标记点”。第三给老项目快速补冒烟测试。历史项目没有测试基建补选择器式自动化成本太高但用YAML写几条AI冒烟用例一天内就能覆盖登录、主流程、关键页面跳转。6.2 不建议当冤大头的场景一是高精度的数值校验。订单金额、库存数量、涨幅百分比这种老老实实走接口断言或者DOM数据提取别让AI帮你读小数点。二是超高频执行。比如每5分钟全量回归一次视觉模型的调用成本会让你的账单很难看。三是完全无人值守且失败零容忍的线上阻断。AI测试现在更适合做快速反馈和趋势判断不适合做那种“必须100%准确错了就线上事故”的硬性门禁。6.3 团队落地时的一个关键建议如果你们团队想引入这套方案我建议先拿一条真实链路做试点比如登录主列表页跑两周记录成功率和维护成本。不要一上来就铺几百条用例因为AI测试的调试方法和传统脚本差别很大团队需要时间适应“写人话”而不是“写选择器”。我还有一个习惯项目里建一个“自然语言指令词库”把写得好、跑得稳的指令沉淀下来。比如“点击右上角带齿轮图标的设置入口它在用户头像左边”这条指令命中率极高后面的人写类似场景直接抄就能少踩很多次“描述不清”的坑。我个人现在的工作流是核心业务链路用AI视觉脚本兜底涉及精确数据的场景仍保留传统断言。两者配合稳定性和覆盖率都能兼顾。开发改版以后我不再像以前那样提心吊胆地等测试红了大部分用例改个描述就能继续跑。这套工具真正的价值不是取代测试工程师而是把我们从“维护一堆脆弱的定位表达式”中解放出来把精力放到设计更好的验证逻辑上。以后再有人问我要不要上AI视觉自动化我的答案一致值得试但先花半小时跑通一个真实用例再谈规模化。如果你也在折腾AI自动化测试欢迎拿我这篇里的步骤当起点把你自己的场景跑一遍感受会比看任何教程都深。