资讯动态

通用Agent下沉移动端测试:从自由发挥到约束探索的工程改造实践

发布时间:2026/10/18 7:54:41 来源:尧图企业网站定制
这个系列写到第九篇前面我们已经把LLM驱动的自动化测试从桌面端一路聊到了移动端元素定位、用例生成、执行器、结果分析该有的零件基本都有了。于是这一篇顺理成章地想到一个方向——把通用的Agent框架直接搬过来让它自己规划、自己执行、自己汇报。移动端自动化这一摊子事是不是就能彻底交给一个大脑了。我抱着这个想法把一套社区常见的通用Agent框架接进移动端测试场景跑了一轮之后发现结论有点反直觉通用Agent框架越通用直接拿来跑测试就越别扭。不是模型能力不行也不是框架本身不好而是测试这种任务对可重复、可解释、可断言的要求和通用Agent默认那种开放任务自由发挥的交互模型天然不在一个频道。这篇就把下沉改造过程中的关键决策、踩过的坑和最后沉淀下来的方案完整拆给你看。1. 通用 Agent 下沉的第一个错觉能规划不代表能测试1.1 任务形态不同开放问答 vs 闭合验收通用Agent的典型任务是帮我整理一下这份会议纪要把搜索结果汇总成三条要点——这类任务有一个共同点没有唯一正确答案只要结果看起来合理就算成功。测试不一样。测试的每一个步骤都对应着明确的预期点击登录按钮之后要么进入首页要么出现错误提示不存在差不多看起来像进入了首页这种模糊地带。我们最开始把通用Agent框架接进模拟项目X的移动端回归时直接用自然语言描述目标验证登录流程正常。框架确实会自己去点输入框、填账号、点下一步但问题很快暴露它会因为界面上的一条偶然提示文案就自作主张地判断登录失败甚至偶尔会把登录成功和注册成功两个页面混淆。后来我们翻日志分析发现不是模型不认字而是它在用开放语义空间的方式处理测试任务——把测试当成理解题做但测试本质上是一道判断题。通用任务和测试任务的核心差异可以这么看维度通用Agent任务测试任务答案形态开放、多元、可协商闭合、唯一、可断言成功标准结果合理即可实际行为与预期一致出错成本重来一次就能补救漏测一个缺陷就是事故过程要求关注结果过程随意过程可复现、可回溯这张表是后续所有改造的总纲。你会发现凡是Agent在通用场景里体现出来的灵活智能到了测试场景里都可能变成不稳定不可控。这不是要抹掉Agent的智能而是要给它重新定一套行为规则。1.2 失败成本不同答错了可以重来测错了就是漏测通用任务里模型答错了用户顶多骂一句再问一次就行。测试场景里Agent判断错了要么把一个真实缺陷放走了要么把一个正常页面标记成失败白白消耗整个团队去排查。这个成本差异直接决定了Agent在测试场景下必须多一套自我约束机制不能随便猜测、不能跳过断言、不能靠幻觉补齐缺失信息。这个约束不是靠prompt写一句请严格按照测试步骤执行就能解决的。我们在第一版prompt里加了大量这种强调结果该乱来还是乱来。后来才意识到通用Agent的规划层擅长的是把大目标拆成子目标但不会自动具备测试领域的预期管理能力。你不可能指望它天生知道等待元素出现3秒是合理的、等待4秒就要报异常这种阈值判断。所以下沉改造的第一步不是调prompt而是重构它的动作空间和观测方式让模型在一个被严格限定的轨道里做决策。2. 动作空间收敛把模型自由发挥改成测试原语 Schema 约束2.1 移动端测试原语的设计原则与分类通用Agent通常让模型直接输出要执行的动作序列。在Web场景这还勉强能用因为页面结构相对规整移动端一旦交给模型自由发挥它可能输出一些看起来合理但根本不可执行的动作比如点击右上角的设置图标然后等待5秒。右上角这种描述在视觉上没问题但在自动化执行器里没法直接转换成坐标或控件句柄。我们把动作空间收敛成一套可枚举的测试原语每一条原语都对应移动端一个最小可执行操作模型只能在这套集合里做选择不能自己发明动作。最终沉淀下来的原语大致分成四类类别原语示例使用场景操作类点击、长按、滑动、输入、清除、键盘操作执行用户动作状态类等待元素出现/消失、获取控件树快照、获取页面文本感知页面状态断言类断言存在/不存在、断言文本匹配、断言元素可用验证预期辅助类截图、OCR识别区域、处理系统弹窗、切换前后台兜底与恢复这里有个容易忽略的点原语数量不是越多越好。数量一旦超过三十个模型的选择准确率就会明显下降。我们在模拟项目X上做过对比原语表从42个收敛到24个之后单轮动作选择准确率提升了将近10个百分点。原则是让原语之间尽量正交能用组合表达的不要单独设计一个动作。比如滑动并点击这种复合动作就不该存在拆成滑动点击两步模型每走一步都有机会重新观测页面这比一个高阶动作更稳。2.2 用 Schema 约束输出而不是让模型自由写操作动作原语定义好之后下一个关键决策是输出格式。我们一开始让模型直接以自然语言输出操作步骤再由解析器去理解结果解析错误比想象中多出不少。自然语言太自由了同一个意思能写出十几种句式解析器为了兼容这些句式要写一堆规则写完还是会漏。后来改成结构化Schema约束模型每次输出必须是一个符合JSON Schema的动作块包含action、target、params、expected等字段。示例是这样的{ action: click, target: { by: xpath, value: //android.widget.TextView[text登录] }, params: {}, expected: { type: element_displayed, value: //android.widget.TextView[text首页] } }这样每个动作自带预期结果执行器执行完动作后自动去校验expected而不是等模型下一步再判断。这一步做完之后Agent的每一次操作都变成可断言的动作后续做失败归因才有证据可查否则每个动作都是一个黑盒出问题只能猜。2.3 为什么这一步能省掉后面大量排查时间用自然语言输出时出了问题很难定位是模型想错了解析器理解错了还是执行器执行错了。结构化Schema的价值在于把这三层分开模型负责决策层Schema负责接口层执行器负责动作层。哪一层出问题看日志格式就能直接定位不用靠猜。这对Agent测试的维护体验是决定性的因为Agent执行失败时团队最痛的不是失败本身而是不知道这个失败该怎么归属。这里再提醒一句Schema校验一定要在运行时做不要只调模型的时候验证。我们在上线初期遇到过一个隐蔽问题——模型在95%的情况下输出是合法的但偶尔会在嵌套参数里多出一个未知字段。如果执行器选择忽略未知字段动作还是能跑但断言条件可能已经悄悄变了。后来我们在校验层把unknown字段直接判为非法输出强制模型重新生成。虽然多花了少量token但执行结果的可信度上来了。这个决策在后面的排查中帮了大忙。3. 观测层重构Agent 的眼睛不能只靠截图3.1 三层观测源控件树、OCR、图像特征通用Agent在多模态场景下通常以截图为主理解界面。但在移动端直接依赖截图有几个麻烦深色模式下部分文字对比度不足动态加载的列表项在截图上看着完整但实际还没渲染完以及系统字体缩放导致模型对控件位置的判断出现偏差。截图不是不能用而是必须作为观测的一部分不能作为唯一依据。我们给Agent搭了三层观测。第一层是控件树通过系统辅助能力拿到当前界面的控件层级和属性这是最可靠的结构化信息。第二层是OCR当控件树拿不到或者控件没有文本属性时用OCR识别界面文字给模型提供文本层面的上下文。第三层是图像特征主要用于定位验证和视觉断言比如确认某个toast提示条是否消失。三层里控件树优先级最高OCR次之图像特征主要用于辅助确认。这个优先级在后面的冲突仲裁里会发挥作用。3.2 弹窗、闪屏与假加载移动端专属干扰在PC端自动化里弹窗通常由被测应用自己控制。移动端最大的变量是系统级弹窗和应用内半透明浮层——它们会出现在任何一步操作之后而且内容高度相似。例如定位权限弹窗、通知授权弹窗、应用更新提示OCR识别出来都是允许禁止以后再说之类的按钮几乎没有区分度。如果不做处理Agent很可能把系统弹窗当成业务弹窗去点。我们专门做了一层弹窗识别器在每次动作执行前先做一次全局弹窗扫描比对当前控件树和OCR文本里是否出现高频权限弹窗关键词如果命中先执行预设的弹窗处理策略再继续原测试流程。这层逻辑不能交给模型临场发挥否则一个弹窗就能让整轮用例路径跑偏而且你很难从日志里看出偏到了哪里。除了弹窗假加载也是移动端专属问题。页面转圈动画可能在内容已经加载完成后仍然显示几秒Agent如果盯着加载中状态就会傻等。我们的状态机里把加载完成定义为目标控件的关键属性出现且转圈动画消失两个条件同时满足才算空闲。这个定义一开始没做好结果Agent经常卡在看到了目标控件但还在等动画消失的僵局里后来把条件改成与或组合才解决。3.3 多源信息冲突仲裁别让模型猜三层观测源同时存在时数据会打架。控件树说登录按钮可用OCR在同一个位置读到了登录但图像特征发现这个区域的按钮处于置灰状态。这种情况在移动端很常见尤其在表单校验未通过时。我们定的仲裁规则是控件树属性优先于OCR文本但图像特征在某些状态下可以推翻前两者。比如控件树里按钮enabledtrue但截图明显置灰就以图像特征为准。仲裁逻辑必须放在观测层不要让模型自己拿两路信息去猜。模型一旦被扔进这种冲突里就会开始编理由解释为什么按钮点不了、为什么断言失败这才是最危险的。你希望模型专注于决策而不是替观测层打圆场。4. 环境扰动才是移动端 Agent 测试的真正敌人4.1 等待策略从固定 sleep 到状态机轮询通用Agent框架在等待这个问题上通常很随意要么让模型自己决定等多久要么干脆用固定sleep。移动端性能波动太大固定sleep只有两个结果——等短了在控件没出现时报错等长了每次操作都拖慢整体执行。我们最后实现了一个轻量状态机空闲、加载中、出错三个状态。每次动作执行后先进入加载中状态轮询目标控件状态同时设置超时上限。超时后不是直接失败而是先触发一次重新取快照。原因是很多超时是控件树漏更导致的重新取一次大概率就好了。这个重试逻辑不能省实测中它能救回大约20%的伪失败。别小看这20%在Agent测试里伪失败是最消耗团队信任感的东西跑十次挂三次就算全是误报大家也会开始怀疑这套方案到底靠不靠谱。4.2 设备性能、系统动画与点击偏移移动端设备性能差异大老设备上动画掉帧会导致控件实际坐标和渲染坐标不一致。我们在模拟项目X的低端机型上出现过一种经典问题模型点击的坐标没问题控件树也显示元素存在但实际点击落在按钮边缘事件被系统判定为点击空白断言失败。这个问题排查了很久最后在日志里发现每次失败的坐标都偏离控件中心几个像素。解决办法是在点击动作里加一个命中校验点击完成后检查目标元素是否获得焦点或发生预期变化如果没有执行一次微小偏移重试。另外部分设备开启了窗口缩放动画控件树刚返回时元素已经存在但视觉上还在移动。我们又加了一条规则点击前如果检测到界面正在进行位移动画先等动画结束。这个规则的误伤概率很低但能显著降低误判尤其是列表项点击场景。4.3 多设备并行下的会话隔离Agent框架在单设备上没问题一旦并行跑多台设备最容易出问题的反而不是模型而是会话上下文串了。我们在接入之初就遇到过设备A的测试路径切换到了设备B上模型拿着设备A的控件树做决策导致设备B上一连串误判而且每一条误判看起来都很有道理。后来我们在框架的每个步骤都显式携带设备标识动作记录、观测快照、prompt上下文三个层面全部按设备隔离隔离层面具体做法动作记录每步动作日志绑定设备标识和会话标识观测快照控件树、截图、OCR结果按设备分别存储prompt上下文模型提示词只注入当前设备的历史信息设备切换、断连、重连也必须重新加载该设备的上下文栈不能直接复用上一个会话。这个听上去很基础但通用Agent框架默认是为单会话服务的下沉到并行测试场景时这一点必须在框架层改掉而不是靠业务侧规避风险。4.4 权限与授权前置处理优于临场处理移动端权限弹窗如果在测试中途弹出不管Agent多聪明让它处理都是一种浪费。它每处理一次弹窗就要多一次观测、多一次思考、多一次动作还会打断原本的测试节奏。更合理的做法是在测试前置阶段就把这些问题清掉。我们在框架里加了一个环境预处理阶段跑测试之前自动完成权限授权、关闭不必要的系统通知、锁定设备屏幕超时必要时通过启动参数直接跳过首启引导页。这套预处理做完之后Agent在测试执行中需要面对的环境干扰减少了一半以上。我的建议是凡是能前置稳定解决的问题就不要丢给Agent临场发挥Agent的智能应该花在真正的业务路径探索上而不是浪费在跟系统弹窗斗智斗勇上。5. 失败闭环Agent 测试最值钱的产出是为什么挂的5.1 三段证据链执行上下文、操作回放、控件树快照传统自动化脚本挂掉日志里能看到是哪一行报错排查相对容易。Agent测试挂掉时模型可能做了二十步操作才失败如果没有完整证据链根本说不清是第几步出了问题。我们给每一次执行都留了三段证据执行上下文prompt、模型选择动作的理由摘要、Schema校验结果、操作回放每一步动作的关键参数和实际执行结果、控件树快照动作执行前后的界面状态对比。一旦断言失败这三样东西自动打包成一份带时间线的报告。排查效率提升非常明显不用再翻原始日志。尤其是模型为什么在第五步选择了这个点击目标从执行上下文里能直接看到它当时的观测输入这比事后反推要快得多。Agent测试本质上还是一个黑盒证据链就是打开黑盒的那把钥匙。5.2 失败归因三类错误分开对待我们把失败归成三类。第一类是环境错误比如设备断连、网络超时、App闪退这类错误和被测功能无关重跑即可。第二类是执行错误比如控件没找到、点击偏移、弹窗遮挡这类错误意味着Agent在特定环境下的动作执行不够稳需要调整原语或等待策略。第三类是产品缺陷这是最想看到的结果说明测试真的发现了问题。归因逻辑分两层第一层用规则引擎粗筛比如检测到设备断连关键词就直接归为环境错误。第二层把粗筛不了的情况交给LLM辅助判断但前提是给模型提供完整的证据链而不是只给一句失败信息。这样伪装成环境问题的产品缺陷才能被识别出来。我们实测中确实抓到过几个这类案例如果只靠规则引擎大概率会被当成环境问题直接放走这些案例后来都成了推动Agent测试落地的最佳论据。5.3 失败恢复进阶不是重跑是续跑通用Agent失败后最常见的处理是重新规划整个任务。这在测试场景里代价太大——一轮移动端回归可能已经执行了十几分钟从头再来既耗时又容易掩盖问题。我们改造成分阶段续跑模式测试流程按业务链路切成多个阶段每个阶段结束会保存会话检查点。失败后Agent可以加载最近一个检查点只重试当前阶段前面的阶段结果保持不变。这里要注意一个边界并不是所有失败都适合续跑。如果产品缺陷已经确认应该停止续跑保留证据走缺陷流程只有环境或执行类错误才尝试恢复。另外续跑时建议把恢复操作也记录进操作回放否则看报告的人会疑惑中间那段操作从哪冒出来的。续跑做得好不好直接决定了Agent测试在长链路场景下的实用价值这比单纯提高单次执行成功率更重要。6. 落地效果与人效账什么时候该交给 Agent什么时候别交给它6.1 一组有参考价值的复盘数据讲一下模拟项目X的改造效果不追求严格统计意义但方向有参考价值。改造完成后大概两周时间我们把原先70多条移动端核心回归用例做了分层处理。约30条高频冒烟用例仍然跑传统脚本剩余40多条中长尾用例交给Agent驱动。单轮回归耗时从人工执行的约4小时压缩到Agent执行加人工审阅合计约1小时路径覆盖率提升约25%还额外增加了不少原先没覆盖到的跨页面状态组合。要说明的是这里面有相当一部分收益来自框架本身的结构化改造而不是模型能力。把动作空间收敛、观测层重构、失败留痕做好之后哪怕用不是最强的模型稳定性也能达到可接受水平。很多团队在评估Agent测试时把注意力全放在模型选型上其实框架层的工程改造才是决定成败的胜负手。6.2 分类决策脚本、Agent、人工审阅三者的边界哪些用例适合继续用脚本来跑答案是那些步骤稳定、断言明确、执行频率极高的用例。脚本在这些场景下最可靠也最省钱。哪些用例适合交给Agent答案是跨页面链路长、前置条件多、组合状态多的中长尾用例以及探索性测试场景。Agent的价值不在于跑得快而在于它能在遇到小偏差时自动调整路径而不是像脚本一样直接报错。人要在哪里介入不是每一步都介入而是在Agent执行完一轮后做集中审阅重点看失败证据链和覆盖率报告。如果Agent发现了一个新路径但这条路径在业务上不该被走到那可能反而是Agent自身导航能力太强导致的过度探索需要在观测层加约束。我的建议是这套分类边界要在一开始就固定下来允许微调但不能让Agent和脚本的边界变得模糊否则维护成本会失控。6.3 最后一条经验下沉改造做下来我个人的体会是通用Agent框架不是不能用于测试但它默认的那种自由感恰恰是测试场景最不需要的东西。你要做的不是给模型更多的发挥空间而是给它一张足够清晰的地图、一套明确的红绿灯规则然后允许它在地图边缘多走两步并把它走过的路完整记录下来。这样一来它既保留了智能体在意外情况下的应变能力又能满足质量活动最看重的可重复和可追溯。从执行结果看Agent最适合的身份不是一个全自主的测试替身而是一个被严格约束的探索者。它负责在长链路和复杂状态组合里帮我们蹚路然后把每一步行动变成可审计的证据。这套思路迁移到Web端和接口层测试同样成立如果你所在的团队也在做类似的尝试强烈建议先从动作空间和观测层入手改造而不是一上来就追求端到端的全自动。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑