本文来自花椒技术部真实工程实践。如果你也在关注 AI 工程化、企业 Agent、MCP、Skill 或研发工具链,文末有「花椒技术交流群」入口,这里汇聚**一线技术从业者,专注代码评审、企业内部 Agent **真实实战落地。想紧跟 AI 前沿动态、交流工程落地经验、少走踩坑弯路.
过去做一次项目线上回归,完整跑下来大约需要两天。现在,借助真机 UI 自动化,核心执行链路已经可以压到十分钟左右。
先看一眼执行现场。

这张图里,左侧有执行步骤和耗时,顶部是时间线,中间是回放画面,右侧保留参数和元素定位。读者不用先听我们解释,也能先看到一件事,执行链路已经有步骤、耗时、时间线、回放和定位记录。
它直接减少了重复点页面、重复看结果、重复整理证据的时间。但如果只把这件事写成提效故事,反而会把真正值得讲的部分盖住。
真机 UI 自动化最容易被误解成一件很简单的事。写一份 YAML,连一台手机,让脚本把页面跑完。演示时能跑通,大家会觉得自动化已经有了。
真正进到回归流程里,问题会细很多。换一台机器,环境还在不在。插了两台手机,脚本会不会跑错设备。一个脚本卡住以后,其他设备要不要继续。失败以后,是暂停、重跑,还是转人工确认。跑完以后,QA 根据什么复核这次结果。
这篇文章想拆的,就是这部分工程能力。
我们 QA 团队现在做的事,是让脚本在真机上动起来之后,继续把环境、设备、队列、异常和报告补齐。我们开始把真机 UI 回归推进成一套可重复、可观察、失败后能处理的工程流程。
二、Demo 和回归之间,差的是一套可控流程
一台手机、一份脚本、一次顺利执行,只能说明入口打通了。回归流程要面对的情况更像日常工作现场。
设备可能不止一台。脚本可能不止一份。每台设备要跑的 checklist 也可能不一样。有的链路跑得快,有的链路要等页面加载,还有一些链路中途需要人工看一眼状态。自动化如果只会一直往前跑,遇到这些情况很快就会乱。
所以我们先把真机回归拆成几个必须明确的动作。
- 执行前先检查环境,避免任务启动后才发现依赖缺失。
- 执行前确认设备和脚本的映射,避免脚本跑到错误手机上。
- 多设备执行时按队列推进,避免某一台设备无限甩开其他设备。
- 失败、暂停、重跑和停止要有不同含义,不能都混成一句失败了再试一次。
- 执行过程要能看见,执行结果要能复核。
- 最后的质量判断仍然由 QA 结合业务风险给出。
这些动作连起来,真机 UI 自动化才不再只是一次演示。它开始具备进入回归流程的条件。
三、环境先变成可检查项
真机自动化的失败,很多时候并不来自业务页面。
Node 版本不合适,ADB 不可用,手机没有授权,Midscene 命令找不到,项目依赖没装好,模型配置缺失,这些都会让任务在真正执行业务步骤之前就停下来。
如果这些问题只靠人临时排查,自动化会变得很脆。今天在一台电脑上能跑,明天换一台机器就不知道从哪里查。更麻烦的是,环境问题和业务失败混在一起以后,QA 很难判断这次回归到底失败在哪里。
我们把环境检查单独前置。执行真机 checklist 之前,先确认基础依赖、设备状态和模型配置都在可用状态。这套检查可以只做诊断,也可以在缺少依赖时给出安装或修复提示。已经具备的条件不重复处理,缺失的部分先暴露出来。
text
- CheckOnly:只诊断,不安装,用来先判断环境是否满足真机执行。
- 基础依赖:检查 Node.js / npm、ADB / platform-tools、Midscene CLI。
- 项目依赖:检查目标项目是否具备 Midscene Android 执行依赖。
- 模型配置:只判断模型相关环境变量是否存在,API Key 只显示 set / not set。
- 设备状态:通过 adb devices -l 确认目标真机处于 device 状态。
- 处理方式:已具备的组件跳过,缺失项给出安装或修复提示。
这里的片段主要来自 Android / Midscene 这条已经固化的环境配置 Skill。它在文章里的作用,是说明我们没有把环境准备留给临场经验。
它让一次失败先有了归因入口。任务没启动起来,是环境没准备好。任务启动后某一步没过,才继续看页面、定位和业务结果。
环境检查不替 QA 做判断。它先把低级失败挡在正式执行之前,让后面的回归结果更干净。
四、设备映射和多设备队列,保证脚本跑在正确机器上
单台手机时,脚本和设备的关系很直观。多台真机同时接入以后,这件事就不能交给默认顺序。
如果只依赖系统发现设备的顺序,脚本可能跑到错误手机上。它不一定会立刻失败,甚至可能继续执行一段时间。可是一旦设备和任务对不上,后面的报告、日志和质量结论都会失去可信度。
我们的处理方式很直接。执行前先列出可用设备和待执行的 checklist,再由使用者确认每条任务队列应该绑定哪台真实设备。确认以后,每台设备作为一条 lane 向前跑。系统会检查重复映射,避免两个队列抢同一台设备。
下面这张图是双机队列运行中的状态页。截图里出现的是 iOS 双机运行场景,可以直接看到多设备队列、运行状态、暂停、重跑和报告入口。端侧实现差异可以后面单独展开,这里先看共同流程。

多设备队列还有一个容易被忽略的细节。并发只是启动方式,队列还要决定多台设备怎样一起往前走。
如果 A 设备第一条任务很快结束,B 设备第一条任务还在运行,A 设备是否马上进入第二条任务,会影响整个回归的观察方式。我们的队列可以按轮次推进,也可以切到人工推进。需要一起进入下一轮时,等当前活跃 lane 稳定以后再继续。需要人工观察时,QA 可以停下来确认。
这张启动消息能看到一次双队列任务被发起后,系统返回了两组队列和监控面板入口。

这类机制承认真机回归本来就复杂,然后把复杂性放到可确认、可观察的位置上。
五、失败、暂停和重跑,让异常能被处理
自动化进入真实回归以后,最怕的是失败语义不清。
脚本失败了,原因可能来自页面变化、元素定位、网络波动、设备状态,也可能是业务真的有问题。如果系统只给一句失败,QA 还是要回到人工排查。更糟糕的是,如果失败后直接重跑,前一次失败现场可能被覆盖,最后只剩一个看起来成功的结果。
所以我们把失败、暂停、重跑和停止拆开处理。
- 失败。保留当前任务的失败结果,后续是否继续由队列规则和 QA 判断决定。
- 暂停。停止当前执行进程,不把它包装成从原步骤继续。
- 重跑。针对当前 lane 的当前脚本重新启动,上一进程要先退出。
- 放弃后续。跳过当前设备剩下的任务,不影响其他设备继续。
- 停止全部。当环境或执行条件已经不成立时,统一结束本次回归。
下面这张运行消息截图里,可以看到 success、paused、Rerun script 和 Start 这些状态。它留下了异常出现后的处理痕迹,能看到流程怎样记录它、处理它,再把结果保留下来。

状态页负责过程,报告负责复核。一次真机 UI 自动化跑完以后,QA 需要看到它到底做过什么。只看到成功或失败两个字,支撑不了质量判断。
开头那张执行界面已经展示了报告结构。Midscene 报告里保留了执行步骤、时间线、回放画面、截图、JSON 视图、参数和元素定位信息。可以顺着这些信息看一遍,是页面真的不符合预期,还是定位不稳定、环境异常或模型执行出现偏差。
这里再放一段短视频,看到真机 App 页面在执行过程中被自动操作
到这里,真机 UI 自动化已经从后台进程变成了可以被观察的执行现场。它有状态变化,有复核入口,也有异常处理动作。QA 不需要靠回忆还原发生过什么。
六、自动化执行不替代 QA 判断,最后给检查清单
真机 UI 自动化解决的是重复执行和过程记录的问题。它不会替 QA 决定这次回归能不能过。
哪些设备要覆盖,哪些链路是核心链路,一次失败能不能接受,什么时候需要转人工验证,什么时候必须停止整轮回归,这些判断仍然要回到业务风险和质量标准里。
这也是我们现在更看重工程能力的原因。把环境检查、设备映射、多设备队列、状态观察、失败处理和报告复核放进一条真实流程里。
如果你的团队也在做真机 UI 自动化,可以先按下面这份清单自查。
- 环境可检查。执行前能确认依赖、设备、授权和模型配置。
- 映射可确认。脚本和真实设备显式绑定,不依赖设备发现顺序。
- 队列可预测。并发、轮次推进和人工推进都有明确规则。
- 过程可观察。能看到每台设备当前任务、步骤、日志和状态。
- 失败可处理。暂停、重跑、跳过和停止有不同语义。
- 结果可复核。日志、结构化结果和报告能支撑 QA 重新检查。
- 责任不混淆。自动化负责执行和留痕,QA 负责风险判断。
从 2 天到 10 分钟,最容易被记住的是时间变化。可这套流程更该保留下来的部分,是设备增加、脚本失败、人工介入和结果复核出现时,它还知道下一步该怎么走。
花椒技术交流群
还在孤军研究 AI 工程化、AI 编程、Agent 落地 ,没人同行交流、没人拆解实战?
这里汇聚一线技术从业者,专注代码评审、企业内部 Agent 真实实战落地。想紧跟 AI 前沿动态、交流工程 落地经验、少走踩坑弯路,欢迎直接加入**「花椒技术交流群」**。群内专属福利拉满:每日精选 AI 行业日报 、文章独家延伸资料、文中未展开的技术细节,全部同步共享。