新闻详情

新闻详情

首页 / 资讯中心 / 详情

Midscene实战:用自然语言驱动安卓UI自动化,告别Appium选择器维护

发布时间:2026/9/26 14:24:35来源:尧图网络
Midscene实战:用自然语言驱动安卓UI自动化,告别Appium选择器维护
上个月我还在为一个安卓原生App的回归测试头疼。Appium脚本越来越长产品每次改版定位器一环套一环光找一个列表里的按钮就要研究半天resource-id和父节点层级。一个登录流程的自动化用例维护成本甚至比写它的时候还高。后来我把Midscene接进来试着用自然语言直接驱动安卓UI第一个感觉就是自动化测试终于不用再“人肉翻译”界面了。Midscene的核心思路很直接——让大模型直接“看”屏幕上的内容通过自然语言指令完成点击、输入、滑动、断言。你说“点击登录按钮填入手机号”它就能自己规划并执行。配合安卓自动化我甚至只用了几句话就把从启动App到完成表单校验的全流程跑通了。这篇文章把Midscene在安卓自动化上的入门到实战写透覆盖核心原理、环境搭建、Agent模式、字段校验和真实踩坑记录适合正在做UI自动化、想用AI降低脚本维护成本或者准备在团队里引入AI Agent的测试开发和前端工程师。1. 搞清楚Midscene的定位为什么自然语言能比选择器更好地做安卓UI自动化1.1 传统自动化和Midscene找元素的逻辑有什么本质不同先站在安卓自动化的角度回顾一下大家平时最常用的工具链UIAutomator、Appium、Airtest。它们有个共同点——定位UI元素靠的是界面属性和树状结构。resource-id、text、content-desc、xpath这些都是脚本眼里的“坐标”。问题在于这些定位方式跟“人怎么看界面”完全脱节。人看到的是“右上角那个灰色返回箭头”“带红色星号的手机号输入框”而自动化脚本看到的是com.example.app:id/et_phone_input这样的资源ID。一旦开发改ID、换布局、动态加载列表定位符一批一批地断。我见过最夸张的一次上游开发只是把两个Fragment合并了一下整个登录流程的脚本就废了一半。Midscene走的是另一条路它把界面同时转换成两个维度的信息——视觉截图和语义化标记。给大模型提供当前屏幕截图以及可操作节点的文本/结构摘要然后模型通过理解自然语言来判断“哪个节点对应手机号输入框”。也就是说不再依赖写死的选择器而是让AI在每次执行时重新“看一遍”屏幕。对于安卓自动化来说这个差异是决定性的。安卓App的UI树经常因为Flutter、Compose、WebView混编而变得混乱很多自绘控件根本没有暴露resource-id。传统脚本遇到自绘控件基本束手无策只能退回去用坐标点一个屏幕尺寸一变坐标就废。Midscene因为本质上是“看图理解”反而能正常处理这类自绘UI。我在实测中让它去点一个Canvas绘制的图表按钮它靠截图和上下文语义一次就点对了。1.2 安卓端凭什么能接入一个为网页设计的AI框架Midscene从Web自动化起家在网页端实现起来有天然优势浏览器本身就是获取DOM结构的最佳通道。到了安卓端它需要解决两个问题一是如何把App界面变成与Web类似的、可被AI理解的结构二是如何把AI决策出的操作真正下发到设备并执行。这两个问题不需要重新发明轮子。安卓侧通过ADB桥获取设备连接再借助UIAutomator或WebDriverAgent这类已有的驱动层拿到界面树和截图Midscene在其中扮演的是“大脑”角色把看到的内容分析后生成任务计划再通过底层的Appium/ADB能力去执行实际点击和输入。你可以把它理解成传统框架提供了手和眼Midscene额外配了一个会思考的指挥中心。我在落地中的体会是Midscene并不要求你完全抛弃安卓原生的驱动能力更多时候它是站在已有自动化能力之上的“解释器”。这也是我建议团队在试验阶段不要一上来就删掉旧脚本的原因。后面第5章会细讲两者怎么互补。1.3 AI“看图”背后的两个隐藏环节实际操作中你会发现Midscene并不是简单地把截图扔给大模型。开发团队在两个环节上做了关键处理。第一个环节是界面标记。把当前屏幕的UI节点树切成LLM能高效阅读的格式过滤掉那些没有交互意义的内容。比如一个布局容器本身不可见、不可点标记环节会把这类节点剔除只保留AI真正需要关注的元素。这个步骤直接决定了大模型的理解准确率也决定了每次调用的token消耗。第二个环节是动作闭环。每次aiAction执行前框架都会记录当前状态执行后再对比前后两帧之间的变化判断操作是否真的生效。如果AI以为点了登录实际上被一个弹窗挡住后一帧的界面对比就会发现异常从而触发重新计划。这个闭环是保证执行稳定性的核心也是为什么Agent模式能在复杂流程里存活下来的原因。2. 环境准备与首条指令让AI先看见你的安卓界面2.1 前置工具清单与几个容易忽略的配置要跑通Midscene安卓自动化不需要一台多牛的生产设备普通中端安卓手机或者模拟器都行但环境上有几处必须确认Node.js 18及以上版本。Midscene的SDK依赖现代JavaScript特性版本太低会直接报语法错误。Android SDK Platform Tools。确保adb devices能列出你的设备。设备开启开发者模式并允许USB调试。首次连接时弹窗授权一定要点“允许”否则后面会一直卡在设备离线。ADB连接模式。可以用USB直连也可以用无线调试前提是PC和手机在同一局域网。很多人跑不通自动化第一步就栽在授权上。USB调试授权弹窗是每次连接新电脑都会出现的如果你用无线调试方式连接还需要保持手机上的“无线调试”开关一直开启。开发者选项里有一项“USB调试安全设置”允许模拟点击不同厂商叫法不一样建议顺手打开。我遇到过一个很坑的情况设备连上了、授权也给了但Midscene发指令进去毫无反应最后发现是系统默认把USB用途设成了“仅充电”交互指令根本过不去。连接后看一眼通知栏确保USB用途选的是“文件传输”或“USB调试”模式。2.2 安装SDK并创建第一个脚本在Node工程里执行npm init -y npm install midscene/android midscene/core如果你网络拉取npm包比较慢可以换国内镜像源但建议把版本锁在package.json里。Midscene更新很快AI模型接口和底层驱动版本都可能影响行为锁版本能减少莫名其妙的问题。接下来写第一个脚本目标只做一件事让Agent截一张当前安卓屏幕然后把屏幕上的内容念出来。import { AndroidAgent } from midscene/android; const agent new AndroidAgent({ deviceId: 你的设备序列号, // adb devices 里能看到 ai: { provider: openai, model: qwen-vl-max, // 推荐视觉模型后续细说 apiKey: process.env.MODEL_API_KEY, }, }); await agent.connect(); await agent.waitForIdle(); const desc await agent.aiQuery(用一句话描述当前页面); console.log(desc); await agent.close();代码看下来很简洁但执行过程中发生了三件事SDK先通过ADB拿一帧截图和当前界面节点然后把截图和节点交给大模型模型把分析结果以结构化文本返回最后打印出来。AI模型的视觉能力在这里是刚需选型见下一节。运行完之后你会发现Midscene“看”界面的方式确实和Appium不同——它返回的是一段自然语言描述而不是某个节点属性。这种输出形态天然适合做业务校验因为你可以直接在提示词里要求“提取当前页面的所有错误提示文案”它会老老实实给你列出来。2.3 视觉模型选型云端API还是本地部署工具装好之后另一个决策点是模型。Midscene本身不生产模型它依赖一个大语言模型的视觉理解能力所以模型选型直接决定识别准确率和单次运行成本。我实测过几个方案简单说一下感受模型方案优势问题适合场景国内大模型视觉API如通义千问VL、智谱GLM-4V中文界面理解好、延迟低、合规省心部分模型对UI元素密集页面容易漏识别大多数国内业务首选OpenAI GPT-4o等海外模型通用能力强、复杂任务表现好网络问题、成本高、国内合规要评估纯英文或全球化产品本地部署开源视觉模型数据不出内网、长期成本低需要GPU资源、效果略打折扣强合规/高用量团队我的建议是先用国内云端视觉模型跑通流程因为中文App的文案识别和语义理解是它的强项。等到用例量大了再把性价比最高的那部分流程迁移到本地模型能压到几乎零成本。模型切换对Midscene来说只是改配置项不影响脚本逻辑这点很省心。3. Agent模式实战从“帮我登录”到字段校验的一条龙3.1 一次AI决策会经历哪些内部步骤如果你只把Midscene当做一个“能听懂中文的点击器”那就太小看它了。它的价值在Agent模式里体现得最明显你给Agent一个目标比如“完成登录”它不会傻乎乎地只点一个按钮而是会自己拆解步骤。我调试的时候观察下来Agent的内部流程大致是这样的观察当前界面判断目标是否已经完成。如果没完成结合目标和当前界面内容产生一个操作候选候选类型包括点击、输入、滑动、返回。执行该操作等待页面变化。再次观察界面评估操作是否达到预期。重复直到目标达成或者达到最大步数限制。这很像人类测试员的工作方式也是它跟传统“录制回放”最本质的区别。传统脚本执行到中途页面多弹了一个广告脚本大概率直接失败Midscene的Agent看到弹窗会先把广告关掉再继续原来的登录流程因为它的任务理解是“我要完成登录”而不是“我要点这个id对应的按钮”。3.2 字段校验是怎么在Agent模式下实现的再回答一个被问很多次的问题用Midscene写字段校验到底怎么写其实在Agent模式下校验被拆成了“执行动作”和“提取并断言”两件事。比如一个注册页面要求手机号格式不正确时提示“请输入正确的手机号”。用Midscene写这个校验大概长这样await agent.aiAction(在手机号输入框中填入123然后点击获取验证码按钮); await agent.waitForIdle(); const toast await agent.aiQuery(提取当前页面出现的提示文案); console.log(校验文案为:, toast); if (toast.includes(请输入正确的手机号)) { console.log(字段校验测试通过); } else { console.log(字段校验测试失败实际文案:, toast); }看到区别了吗校验逻辑还是你写的但“找到输入框、填入非法内容、点击按钮”这些事情全部交给了AI。最妙的地方在于即使输入框的位置、样式、id全变了只要页面上的可点击元素和语义还保持原有状态这条用例就不用改。当然这不意味着断言可以偷懒。Midscene对“提取”的处理是返回结构化文本你仍然需要自己判断期望值。我的建议是把“获取界面状态”彻底交给AI把“业务断言”坚决留在代码里。AI负责看得准你负责判断得对。3.3 Agent规划失败的场景Agent模式看起来很美但它也有失效的场景。最典型的是界面上的元素长得像、语义重叠比如一个页面里有两个“登录”按钮一个在顶部广告区一个在底部功能入口AI可能点错。另外页面加载特别慢时Agent观察到的界面还是一半空白它会基于残缺信息做出错误决策。遇到这个问题我的处理习惯是给操作加上更精确的限定词例如“点击页面底部导航栏中的登录按钮”。如果还是失败就在关键节点用waitForIdle或固定等待手动控制节奏而不是把等待逻辑全部托付给AI判断。AI能看、能规划但网络状态和渲染时序它管不了测试工程师仍然要负责节奏控制。4. 安卓App真实案例一个登录流程的完整拆解4.1 业务场景与被测App说明先交代一下被测App的形态一款原生安卓应用登录入口藏得比较深启动后需要先处理隐私协议弹窗再进入“我的”页面点击头像区域才会触发登录页。登录页有手机号、密码、验证码三个输入区还有“登录”按钮。这种流程让Appium来写光是处理弹窗、多页面跳转、动态加载等待就要写很多样板代码。用Midscene跑这个流程思路是直接描述用户视角的操作。下面是我在实际项目中跑通的完整脚本注释写得很详细可以直接作为参考。4.2 从点击入口到提交表单的完整代码import { AndroidAgent } from midscene/android; const agent new AndroidAgent({ deviceId: R5CT20XXXXX, // adb devices 里的序列号 ai: { provider: openai, model: qwen-vl-max, apiKey: process.env.MODEL_API_KEY, // 也可以接本地部署的视觉模型看团队成本 }, timeouts: { action: 30_000, // 单步AI操作超时 task: 120_000, // 整个Agent任务超时 }, }); await agent.connect(); // 1. 启动被测Apppackage和Activity可以从manifest里查 await agent.launchApp(com.example.app, .MainActivity); await agent.waitForIdle(); // 2. 关闭隐私协议弹窗 await agent.aiAction(关闭隐私协议弹窗如果有的话); await agent.waitForIdle(); // 3. 进入我的页面 await agent.aiAction(点击底部导航栏中的我的入口); await agent.waitForIdle(); // 4. 点击头像进入登录页 await agent.aiAction(点击页面左上方的头像区域); await agent.waitForIdle(); // 5. 填写手机号 await agent.aiAction(在手机号输入框中填入13800138000); await agent.waitForIdle(); // 6. 填写密码 await agent.aiAction(在密码输入框中填入Test123456); await agent.waitForIdle(); // 7. 点击登录按钮 await agent.aiAction(点击登录按钮); await agent.waitForIdle(); // 8. 断言是否进入首页 const homeText await agent.aiQuery(提取页面顶部搜索框或首页标题的文案); if (homeText.includes(首页) || homeText.includes(搜索)) { console.log(登录流程验证通过); } else { console.log(登录失败当前页面:, homeText); } await agent.close();这个脚本里没有一条resource-id这是我在向团队演示时最喜欢强调的点。只要页面结构不发生彻底推翻这套脚本就可复用。后面产品做过两轮UI改版登录流程的脚本一个字没改仍然能稳定跑通。4.3 真实运行时的观察与等待问题第一次跑的时候我的脚本在“点击登录按钮”那一步反复失败。加日志一看发现App收到点击后没有立刻跳转而是先转了两秒半的加载动画。Midscene的Agent在动画还在转的时候就去观察界面发现页面没变化于是误以为点击没生效甚至重复点了一次导致后面多了一个“登录中”的Toast遮挡。解决方式不是无限调大timeout而是按安卓UI的特性做了几件事在关键操作后主动waitForIdle让出动画时间。对可能弹出的系统级对话框在提示词里用“如果有的话”这类条件描述避免Agent强求关闭。对登录这类异步请求不要立刻断言先等待固定时长再让AI重新观察界面。这些都是传统自动化里“显示等待”思路在AI自动化层面的延伸。AI能看、能想但它仍然不知道网络请求什么时候回来等待策略依然是测试工程师要负责的事。4.4 测试报告中如何留证据还有一点值得专门说AI自动化的日志比传统自动化更有价值因为Agent每一步都有“决策依据”包括当前截图、模型思考、执行动作这三个维度。把它们一起落盘到测试报告里线上定位问题时会非常清楚。我用的做法是给AndroidAgent挂一个事件监听把每步的截图和动作文本写进一个JSON文件再配合测试框架的附件上传。这样测试报告里能直接看到Agent每一步看到什么、做了什么决策、最终结果如何。这个信息量是传统脚本只记录“click成功/失败”完全比不上的。5. 和Appium对比后我决定在哪些场景用Midscene5.1 两类框架的真实差异很多读者第一个反应是那Midscene是不是要取代Appium我的判断是“部分取代但远不是全部”。下面这张表是我基于大半年使用经验做的对比未必代表官方立场但足够真实维度传统Appium/UIAutomatorMidscene/AI Agent元素定位resource-id/text/xpath写死自然语言描述运行时动态识别用例维护UI一变就要改脚本大多数业务描述不变就不用改脚本编写速度需要查树、试层级一句话描述目标稳定性高但依赖定位符准确依赖模型能力和提示词质量运行速度秒级每步AI推理通常慢3-5倍调试手段成熟的日志/截图/录制日志包含思考过程但工具链较新成本免费/开源工具链AI调用费用开发时间离线可用完全离线需要AI模型服务本地或云端稳定性这一点我特别想展开。传统框架的稳定性本质上是“确定的”——只要元素没变反复跑一百次结果都一样Midscene每次判断都有AI推理引入的概率性同一个脚本上午能过下午可能就失败。这个特性决定了它不适合做那种对成功率要求极高的精确回归门禁而非常适合做探索性测试、冒烟测试、UI改版后的回归摸底。5.2 我推荐的组合用法落实到工程上我是这样组合的高频、核心、对稳定性要求极高的路径继续保留Appium脚本保证CI门禁严格。UI改版频繁的业务功能、活动页、流程冒烟用Midscene的Agent快速覆盖人工确认一轮后并入回归。新需求开发阶段用Midscene做探索性测试让Agent按照一句话目标自己跑一遍流程往往能发现一些写用例时没想到的边界场景。这个组合的好处是你不需要推翻现有资产又能让AI在最容易变、最容易漏的地方发挥价值。团队引入AI自动化最大的成本不是工具而是信任。先让它在一个不影响主线的范围里跑一段时间看到效果再逐步扩大范围。5.3 速度、成本和成本模型关于成本团队负责人一定会问。按我的经验一个10步左右的登录流程单次完整运行大约40到90秒比Appium的10到15秒慢不少费用方面使用云端视觉模型一次完整流程大概消耗几万到十几万token折算下来一次几分钱到几毛钱。但如果跑的用例量很大一个月累计下来也是一笔不小开销。如果对成本敏感可以往两个方向优化一是用本地部署的开源视觉模型替代云端API环境允许的话几乎零成本二是只在关键流程和变更高频场景用Agent其他路径继续用传统脚本成本模型会立刻好看很多。6. 落地的坑与建议团队要引入时先看这些6.1 设备连接不上的常见原因和排查顺序安卓自动化老生常谈的问题在Midscene里一个都不会少。设备连接失败时建议按这个顺序排查先执行adb devices确认设备状态。如果显示unauthorized去手机上重新授权并勾选“一律允许”如果显示offline拔掉USB重插或者用adb kill-server adb start-server重启ADB服务如果设备列表正常但Midscene连不上检查deviceId是否写对尤其多设备的时候容易把模拟器id和真机id混在一起。还有一个极容易被忽略的点部分安卓系统连接PC后会自动进入“仅充电”模式USB调试虽然打开了但实际没有建立起交互通道。解决办法是连接后看一眼通知栏确保USB用途选择的是“文件传输”或“USB调试”而不是“仅充电”。这个原因引起的连接失败设备管理器里看起来一切正常但任何自动化指令都发不进去排查起来特别容易绕弯路。6.2 提示词没写好的典型症状AI自动化的瓶颈90%在提示词。我总结了三个典型症状对应的解决方法也一并列出来描述太模糊“点一下那个按钮”——AI不知道是哪个按钮。改成“点击页面中央带有‘立即领取’文字的橙色按钮”。描述带错位置“点击右上角的登录”——但页面上登录在左上角。位置描述尽量以当前屏幕为准不要凭记忆。一次塞多个动作“先填用户名再填密码最后点登录”——Agent虽然能拆解但单条指令过于复杂时中途任何一步失败都很难定位。我的经验是单条aiAction尽量只表达一个动作目标元素加上位置、颜色或前后语境限制词操作完成后单独等待。把复杂目标留给Agent模式把精确动作留给自己写提示词这个分工适合大多数场景。6.3 从试点到规模化落地我推荐的节奏最后聊一个工程心态。AI自动化目前还不是一个“完全自主测试”的银弹它的稳定性和可解释性都还有提升空间。但它有一个很确定的价值——当UI界面千变万化时它是成本最低的那双“眼睛”。在我自己的实践里最快出效果的场景反而不是核心用例而是手工测试里最烦的重复性操作不同账号登录、不同文案校验、多设备兼容性冒烟。以前这些场景要么人肉点点点要么写一大堆参数化脚本现在我用Midscene写一套通用流程账号、跳转、断言全部通过提示词和提取结果实现维护量小了整整一个量级。团队引入的时候还有一点建议试点范围不要铺太大先挑一个业务高频、改版频繁、又不太影响主流程的用例比如注册页的字段校验。跑一个月把提示词风格、模型选型、等待策略这些手感练出来再逐步扩大覆盖范围。AI自动化的价值不是一次性上线而是持续迭代中慢慢积累出来的。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

WeWrite 3种安装方式实战:Claude Code、Codex、OpenClaw全平台快速上手 2026/9/26 15:00:37

WeWrite 3种安装方式实战:Claude Code、Codex、OpenClaw全平台快速上手

WeWrite 3种安装方式实战:Claude Code、Codex、OpenClaw全平台快速上手 【免费下载链接】wewrite 公众号内容全流程 Skill,从热点抓取到微信草稿箱,一句话跑完整条内容管道 项目地址: https://gitcode.com/gh_mirrors/wew/wewrite WeW…

阅读更多 →
DB2 V11.1安装实战:从下载到实例创建与Docker部署避坑指南 2026/9/26 15:00:37

DB2 V11.1安装实战:从下载到实例创建与Docker部署避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
WorkBuddy Enterprise企业级Agent平台:SkillHub技能沉淀与团队协作实战 2026/9/26 15:00:30

WorkBuddy Enterprise企业级Agent平台:SkillHub技能沉淀与团队协作实战

1. 从「超级个体」到「超级团队」:这个平台到底在解决什么问题 第一次看到「WorkBuddy Enterprise」这个名字,我脑子里蹦出来的第一个念头是:腾讯云终于把 CodeBuddy 那套东西往企业级方向推了。如果你最近关注过 AI 编程助手这个赛道&#x…

阅读更多 →
Atlas 300V 24G推理加速卡上运行YOLO:从概念到部署全解析 2026/9/26 15:00:30

Atlas 300V 24G推理加速卡上运行YOLO:从概念到部署全解析

最近在好几个技术群里连续看到同一个问题:“Atlas 300V 24G是运算加速卡吗?”“有没有人用Atlas部署过YOLO?”这俩问题其实是同一件事:很多人刚拿到昇腾推理卡,想把手里的目标检测任务跑起来,结果第一步就卡…

阅读更多 →
Python+OpenCV疲劳驾驶检测源码:EAR/MAR算法与工程避坑指南 2026/9/26 15:00:30

Python+OpenCV疲劳驾驶检测源码:EAR/MAR算法与工程避坑指南

简介:这是一套面向计算机相关专业学生与项目实战学习者的疲劳驾驶检测完整项目包,基于Python与OpenCV实现,可直接用于毕业设计、课程设计或期末大作业。项目围绕人脸关键点定位与眼部状态分析展开,通过摄像头实时判断驾驶员疲劳程…

阅读更多 →
WinCC V16 ADODB连接SQL Server工业级实践指南 2026/9/26 15:00:30

WinCC V16 ADODB连接SQL Server工业级实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉