用 Midscene.js 跑通视觉 UI 自动化测试:一份从零上手的完整指南
2026/9/11 15:13:54 网站建设 项目流程

用 Midscene.js 跑通视觉 UI 自动化测试:一份从零上手的完整指南

【免费下载链接】midsceneGUI Agent for E2E Testing项目地址: https://gitcode.com/GitHub_Trending/mid/midscene

给一个界面天天在变的 App 写回归测试,你可能经历过这种事:发布前一天,前端重构了一批类名,两百条用例里有六十条在选择器上挂掉。Midscene.js 走的是另一条路——它让多模态大模型直接看截图来定位元素、执行操作,你用自然语言写测试步骤,不需要维护任何选择器。这是一套面向 E2E 场景的 GUI Agent 工具链,覆盖 Web、Android、iOS、HarmonyOS 和桌面端,适合正在被 UI 自动化维护成本困扰的测试工程师和开发者。

三步跑通第一个视觉脚本

装好 CLI

先确认终端里 Node.js 是 20.19 以上、22.12 以上或 24 以上,CLI 部分执行路径依赖的构建工具链会拒绝更旧的版本。然后全局安装:

npm i -g @midscene/cli

配好模型

在运行目录放一个.env文件(dotenv 约定,不写export),填入你的多模态模型配置:

MIDSCENE_MODEL_BASE_URL="https://你的模型服务地址/v1" MIDSCENE_MODEL_API_KEY="你的API密钥" MIDSCENE_MODEL_NAME="模型名称" MIDSCENE_MODEL_FAMILY="模型系列"

注意.env必须放在工具运行目录下,跟 YAML 文件在哪没关系。

跑第一个脚本

新建bing-search.yaml,内容只有几行:

page: url: https://www.bing.com tasks: - name: 搜索天气 flow: - ai: 搜索 "今日天气" - sleep: 3000 - aiAssert: 结果显示天气信息

执行midscene ./bing-search.yaml,命令行实时输出进度,结束后在输出目录生成 JSON 结果和 HTML 可视化报告。

一张截图能替代多少选择器

把 Midscene.js 想象成一个视觉测试员:你递给他一张屏幕截图和一句"点击登录按钮",他扫一眼图就找到位置点下去,全程不需要知道按钮的 class 叫什么。这就是纯视觉驱动的含义——元素定位只依赖截图,DOM 结构和可访问性树完全不参与。

为什么坚持这么做?因为很多真实元素根本"看不见"在结构里:没有语义标记的纯图标按钮、canvas 画出来的界面、跨域 iframe 里的内容,对传统 DOM 方案都是盲区,而对一张截图来说统统平等。另一个直接好处是测试语义变了:断言验证的是用户实际看到的画面——颜色、高亮、布局,而不只是"某个 DOM 节点存在"。

看懂架构:从模型调用到平台适配

源码分几层,各管各的事:

  • 核心层packages/core/src/agent/目录是规划与执行的主脑,ai-model/负责多模态模型的接入与解析。
  • 平台适配层packages/web-integration/(Playwright、Puppeteer)、packages/android/(ADB + scrcpy 投屏)、packages/ios/(WebDriverAgent)、packages/computer/(桌面键鼠与截图)。
  • CLI 层packages/cli/:负责加载.env、批量执行 YAML、汇总结果与生成报告。
  • 可视化层apps/playground/apps/report/apps/studio/:浏览器侧边栏、报告页面和桌面应用。

写用例时你只接触最上面两层:一段 YAML 或几个 Agent API 调用,底下怎么切图、怎么问模型、怎么落到手指或鼠标,不用关心。

实测三种最常用的操作

aiAct/ai规划执行、aiQuery结构化提取、aiAssert断言,是日常用例的三板斧。

用自然语言驱动点击和输入

前面 Bing 的例子就是最小组合。同一个 YAML 结构换个开头就能切到真机,比如 Android:

android: deviceId: s4ey59 # adb devices 可查 tasks: - name: 地图导航 flow: - ai: 打开地图应用 - ai: 在搜索栏输入 "杭州西湖",然后点击搜索按钮 - aiAssert: 显示了西湖的路线规划页面

iOS 把开头的android:换成ios:(配wdaPort)即可,任务主体一字不动。

让模型吐出结构化数据

aiQuery可以带类型声明,返回的 JSON 直接进断言或落库。在 Playwright 项目里:

const agent = new PlaywrightAgent(page); const items = await agent.aiQuery( '{itemTitle: string, price: number}[], 找出列表里的商品和价格', ); await agent.aiAssert('列表第一件商品显示在库存');

注意点是描述里尽量给出字段和范围的约束,模型返回的结构会更稳。

断言验证用户看到的东西

aiAssert是视觉断言,适合验证高亮、颜色、布局这类"看起来对不对"的状态,这些用 DOM 断言很难覆盖。调试时建议加--headed打开浏览器窗口,或--keep-window结束后保留窗口,肉眼对照执行过程比只看报告快得多。

压低维护成本的两个常用手段

问题:重复执行太费模型调用,怎么办?

做法:给任务加缓存标识agent: { cache: { id: "my-cache" } }。相同的规划指令和元素定位会命中缓存、跳过模型调用,官方文档里的实测案例执行耗时从 51 秒降到 28 秒。缓存文件落在./midscene_run/cache,失效时自动回退到重新分析,不会卡死;查询类操作(aiQueryaiAssert等)永远走实时结果,不会被缓存。

问题:想把 Midscene.js 塞进现有 Playwright 项目?

做法:把现有page对象直接交给PlaywrightAgent,测试文件里的其余断言照旧写。集成细节见 集成 Playwright 文档。批量跑脚本则用通配符:midscene './scripts/**/*.yaml',每个脚本各自生成报告,另有汇总的 JSON 结果。

四个高频问题快速排查

  • 现象:装完 CLI 一运行就报 RspackUnsupported Node.js version原因:Node 版本低于 20.19。解法:升级 Node 后重装全局 CLI。
  • 现象:脚本报模型未配置,明明.env里写了。原因.env放错了目录。解法:它必须在工具运行目录下,与 YAML 所在目录无关;也可以用全局环境变量替代。
  • 现象:结果忽对忽错,像是用了旧数据。原因:上次运行留下的规划或定位缓存命中了过期状态。解法:调试期配cache: false,或删掉./midscene_run/cache重来。
  • 现象:Chrome 扩展里调 Ollama 本地模型报 403。原因:浏览器侧请求被拦截。解法:设置环境变量OLLAMA_ORIGINS="*"再重启浏览器。

和传统方案放在一起对比

选择器/DOM 方案Midscene.js 视觉方案
界面重构后批量改选择器截图仍可读则照常通过
纯图标按钮、canvas结构里定位不到截图里看得见就能点
跨域 iframe基本不可达截图无跨域问题
验证渲染效果只能验证节点存在能断言颜色、高亮、布局

下一步

Midscene.js 把"找到元素"这件事从代码搬到了模型里,维护成本随之从选择器转移到了自然语言描述上,而后者显然更接近界面本身。如果还想往下走:克隆仓库 https://gitcode.com/GitHub_Trending/mid/midscene 跑一遍示例,或先读 基本概念文档 把aiActaiQueryaiAssert的边界弄透,再挑一个现有用例试着用截图重写。

【免费下载链接】midsceneGUI Agent for E2E Testing项目地址: https://gitcode.com/GitHub_Trending/mid/midscene

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询