☰
移动端自动化测试框架ARTEMIS:双模式架构的稳定性与探索之道
2026/10/18 11:58:54 网站建设 项目流程

做移动端自动化这几年,我最大的感受是:传统脚本方案在稳定性和可维护性上已经卷到头了,而纯靠 LLM 自由发挥的“自动驾驶式”测试,又总让人心里没底。直到我自己动手搭了一个名为 ARTEMIS 的移动端自动化测试框架,把两种思路揉在一起,才真正解决了“既要覆盖率、又要稳定性”这个看似矛盾的需求。这篇系列第 5 篇,我就把 ARTEMIS 的双模式架构从设计到落地完整拆一遍,重点讲清楚它为什么能兼顾探索能力和执行可靠性,以及其他团队照搬这套结构时最容易被忽略的几个细节。

1. 为什么是“双模式”:从一次失败的经历说起

1.1 单一模式的瓶颈:脚本太死,纯 LLM 太飘

早期的方案我试过两种极端。第一种是传统的录制回放加元素定位,用 Appium 那套思路,写死每个按钮的 resource-id 和坐标。结果是个噩梦:产品版本一迭代,UI 布局稍微调整,脚本就大面积失效;而且这种方案完全没有办法覆盖到我没有提前预判到的异常路径,比如某个弹窗在弱网环境下延迟了三秒才出现。

第二种方案则截然相反,我一开始就觉得“既然 LLM 聪明,那就让它完全自主操作”。模型拿到当前屏幕截图和 XML 结构,自己决定点哪里、滑不滑动。设想很好,但实际跑起来问题更大:模型偶尔会陷入循环,在一个页面反复点同一个位置;遇到权限弹窗时会连续点“允许”好几次;更离谱的是,有一次模型把“取消”按钮识别成“确定”,一轮回归测试下来应用数据被清空了。

这两次经历让我意识到一个核心问题:移动端自动化的本质是“在不确定的环境中做确定的事”。而单一路径,无论靠脚本还是靠模型,都无法同时满足“确定性”和“应变性”。所以我才下定决心,做一套能在这两种模式之间自由切换的系统,它需要像人一样分“执行计划”和“临场发挥”两种状态。

1.2 双模式架构的核心定义:计划模式与探索模式

ARTEMIS 最终形成的就是两条既独立又协作的执行链路。

第一种叫受控计划模式,内部代号 Executor Mode。这种模式下,LLM 只负责在动作执行前生成一份结构化的测试计划,也就是把“货比三家跳到结算页”、“输入优惠码”、“校验优惠金额”这些步骤拆成指令序列。实际在设备上执行的还是确定性代码,每一步走完后都校验界面状态是否符合预期,如果不符合就停下并上报。这保证了回归测试的稳定性。

第二种叫自主探索模式,内部代号 Explorer Mode。这种模式下,LLM 直接与界面交互,实时观察当前屏幕状态,自主决策下一个动作。ARTEMIS 不会强制校验每一步的对错,而是设定了一系列“安全护栏”和异常退出条件,比如发现页面跳转到了登录页、连续操作超过 N 次没有触发状态变化,就会自动终止并标记异常区域。这个模式专门用来做探索性测试,目的就是发现那些脚本设计阶段根本想象不到的缺陷。

双模式之间不是并列关系,而是通过一个中央调度器动态切换。我在设计时特意强调过一个原则:切换不是靠人手动配置,而是由运行时上下文自动触发。这一点是 ARTEMIS 与市场上其他 LLM 测试框架最大的区别,后面我会专门展开讲。

2. 受控计划模式:让 LLM 当指挥官,而不是操盘手

2.1 计划生成阶段的 Prompt 与约束设计

受控计划模式的第一步是把自然语言测试需求转化为机器可读的测试计划。这个阶段的目标是生成类似于“在 checkOutPage 上执行 tap(checkoutButton),然后等待 networkIdle,再执行 input(couponCode, 'XMAS2026')”这样的原子指令。

为了高质量生成,ARTEMIS 在 Prompt 构造上做了三个关键约束:

第一,提供完整的页面状态上下文。不是只给截图,而是把当前页面的可交互元素列表连同语义描述一起作为上下文。这些描述来自我自研的 UI 理解模块,它会把“screen=[cartPage], element=[confirmBtn, type=button, text=去结算]”这样的结构化信息转成 JSON 注入 Prompt。

第二,指令操作必须遵循白名单。系统把所有可能执行的动作归纳为 6 类:tap、longPress、inputText、swipe、scrollTo、waitFor。任何不在白名单里的动作请求都会被拒绝,确保 LLM 不可能生成类似“调用系统设置接口”这样越界的行为。

第三,计划必须带有前置条件和预期结果。每一步除了动作本身,还要附上执行前的 UI 状态指纹(precondition)和预期执行后的状态指纹(postcondition)。这样脚本执行阶段才能做实时校验,因为 LLM 生成的计划如果不带校验点,那本质上还是瞎跑。

2.2 执行引擎与状态校验机制:报错后怎么办

执行引擎接收到计划后,会向量化解析每一个指令并交给底层的移动端驱动层执行。在执行过程中,最关键的设计是状态指纹比对。

所谓状态指纹,是我开发的一套轻量级算法。当计划中的某一步执行完毕,系统会立刻采集当前屏幕的关键元素集合、文本内容、页面路径,通过 MD5 生成一个指纹值。然后与 LLM 在计划阶段预测的 postcondition 指纹做比对。如果一致,就推进下一步;如果不一致,分两种情况处理:

  • 如果当前指纹和预期只差在非关键元素上,比如一个列表页多加载了一条商品,系统会自动进入“宽松匹配”模式,不打断整个测试流程。
  • 如果关键路径差异过大,比如预期停留在结算页,实际却跳转到了首页,则立即触发“失败路由”。

失败路由里 ARTEMIS 会先自动截图并抓取页面 XML,把差异元素高亮出来,同时回传一份诊断报告生成失败原因候选。这时候 LLM 再做二次分析,判断是应用功能缺陷,还是计划生成错误,还是元素定位不准确。这个步骤特别重要,因为传统框架只能告诉你“跑挂了”,而 ARTEMIS 能告诉你“因为什么挂的,哪个环节出了问题”。

2.3 受控模式的适用场景与典型收益

这套模式最适合的是高重复、高确定性的回归测试和核心业务流程巡检。我们团队内部的登录、支付、订单列表、消息推送这四大核心链路,已经全部迁移到该模式下执行。相比之前的纯脚本方案,收益非常明显:

第一,脚本维护成本大幅下降。UI 更新时不再需要人工逐个调整元素定位符,因为 LLM 会自动根据新的页面状态重新生成计划,相当于把“脚本维护”变成了“意图维护”。

第二,失败分析速度加快。以前收到一条失败记录,要人工翻日志、比对截图,现在失败信息自带归因分析,定位时间从平均 40 分钟缩短到了不到 10 分钟。

第三,跨平台复用性好。因为计划是语义化的,并不是绑定在某个具体平台上的坐标序列。iOS 和 Android 的同一套业务用例,只需要在平台适配层做转化,不需要重写计划。实际测试下来,跨平台用例复用率能接近 80%。

3. 自主探索模式:让 LLM 当测试员,靠护栏兜底

3.1 探索模式的状态空间建模与感知层设计

如果说受控模式是让 LLM 在轨道上开车,探索模式就是让它在空旷场地里自由行驶,但周围必须有围栏。探索模式的关键第一步,是构建一套状态空间模型。

每次探索操作前,ARTEMIS 会采集三类感知数据:

  • 视觉层:一张经过降噪和裁剪的屏幕截图,保留关键区域,压缩之后传给视觉编码器。
  • 结构层:当前页面的视图层级树,包括控件的类型、坐标、可点击属性、文本标签。
  • 语义层:OCR 提取出的页面文本内容,结合预分词结果,用于让模型理解页面的业务含义。

这三层数据会拼接成一个统一的观察上下文。我测试下来发现,只给截图不给 XML 时,LLM 对元素位置的理解很容易出现偏差。而只给 XML 不给截图时,模型又难以理解复杂的图形交互相。只有三层数据融合,准确率才足够稳定。

3.2 动作决策链:CPU 式推理与历史记忆池

探索模式的动作决策不是“看到什么就点什么”的即时反应,ARTEMIS 实现了一条完整的决策链。模型每次执行动作前,内部会经历四个阶段的推理:

  1. 理解当前页面状态:用自然语言描述当前页面发生了什么,比如“当前处于商品详情页,底部有加入购物车按钮,用户评价区域已滚动至顶部”。
  2. 确定探索目标:基于本次测试任务意图,决定下一步要验证什么功能,比如“验证评价区域是否存在异常布局”。
  3. 选择动作并预估结果:从动作空间中选择一个操作,同时预估操作后页面会变成什么样,比如“点击展开全部评价,预期显示完整评价列表”。
  4. 自我修正:如果上一步的动作没有导致页面状态变化,则自动修正策略,避免做重复操作。

这套决策链不是一次性完成的,它依靠一个历史记忆池。每一轮探索的观察、动作、结果都会被存储为 token 向量,供后续决策调用。当模型发现自己连续出现相同的动作而没有新状态产出时,会主动放弃该路径,换一个方向继续探索。我在实际运行中发现,加入历史记忆池之后,探索覆盖率比无记忆的随机探索模式提升了接近 40%。因为无记忆模式下模型容易陷入局部最优,而记忆池能让它像人一样记住“这条路走过了”,从而更愿意尝试新路径。

3.3 安全护栏与控制参数:如何防止“翻车”

探索模式最令团队担心的就是“翻车”。为了防止测试机器在探索过程中误操作、删除数据或进入不可逆页面,ARTEMIS 定义了三层控制护栏:

动作合法性检查。每个动作在真正执行前,必须通过合法性校验。校验规则包括最低层级安全策略,比如非当前页面内的元素才允许点击、非输入框控件不能执行输入操作、涉及删除和退出的动作需要二次确认。

状态转移边界检查。系统维护了一个状态转移表,记录哪些页面允许跳转到哪些页面。如果 LLM 试图从 A 页面直接跳跃到未定义关系的页面,护栏会拦截动作。这里有个例子,购物车页面理论上不应该直接跳到个人中心,若模型尝试这么做,说明它可能误判了页面结构。

操作频率与步数限制。探索模式默认最大步数为 30 步,当步数用尽或连续 5 步没有新页面状态产生时,自动终止。另外还启用了“冷却机制”,同一个页面中连续 3 次点击同一控件会被禁止。

这些护栏不是增加复杂度,而是在模型的自由度和系统的安全性之间找平衡。从实际测试效果来看,护栏虽然拦截了部分模型尝试的“边缘操作”,但这些被拦截的路径反而能暴露很多潜在缺陷,因为 LLM 之所以尝试那些操作,通常是因为页面状态误导了它。

4. 双模式的调度中枢与模式切换策略

4.1 为什么需要调度器而不是固定分支

如果双模式只是通过人工配置来选择,那它就只是一个空壳。ARTEMIS 的调度中枢,解决的正是“什么时候该用哪种模式”的问题。

调度器本质上是一个轻量级的策略引擎。每一次测试任务进入系统时,会被分解为多个测试目标,调度器会为每个目标分配模式。分配的依据来自三个信号:

  • 任务类型:回归验证、冒烟测试、数据一致性检查这类明确目标,优先进入受控计划模式。而异常路径探索、竞品功能对比、新版本兼容性摸底这类开放目标,更适合探索模式。
  • 页面状态的不确定性:如果当前被测页面最近一周有过 UI 变更记录,稳定性未知,调度器会倾向先使用探索模式做摸底,等确认页面状态稳定后再切换回计划模式。
  • 实时错误信号:在计划模式执行过程中,如果失败路由触发的次数超过阈值,调度器也会把它临时转为探索模式,让模型更自由地去分析当前页面的异常表现,而不是紧盯着原计划纠结。

通过这种动态切换策略,ARTEMIS 能做到同一套测试集在不同版本上使用不同策略,但不需要测试人员介入修改。这是我最满意的设计之一,因为它在自动化领域真正实现了“测试策略的自动适应”。

4.2 调度状态的监控与可视化:执行进程的丹田

调度器运行过程中,会产生大量的状态记录。我建立了一个扁平化的“执行进程面板”,核心指标包括:

  • 当前执行模式:计划模式还是探索模式。
  • 模式切换计数:一段时间内切换的次数,如果过于频繁,系统会提示可能页面状态存在紊乱。
  • 探索覆盖率:当前探索模式已访问的页面节点占全部可达节点的比例。
  • 稳定度分数:基于成功操作数和失败操作数计算得出的综合指标。

这些指标除了用于运维查看,还会反馈给调度器作为策略调优的依据。举个例子,如果稳定度分数低于 60 分,调度器会自动加大计划模式的比例,减少探索模式的执行。反过来,如果探索覆盖率长期不走动,会适当放宽护栏限制,让模型有更大操作空间。

4.3 双模式共享的基础设施对齐

虽然是双模式,但底层基础设施必须完全一致,这是 ARTEMIS 能够稳定运行的前提。我强调这一点是因为不少团队在做类似架构时,容易把两种模式做成两套独立系统,导致执行环境、日志格式、设备管理都不统一,后期数据分析和问题追踪会变得非常痛苦。

ARTEMIS 的做法是共用三套底层服务:

  • 设备管理池:负责 iOS 和 Android 真机及模拟器的统一调度、并发控制、安装卸载应用。
  • 观测回传管道:统一采集截图、日志、性能指标、Crash 信息,无论哪种模式执行的任务都通过同一条管道回传。
  • 结果存储与报告引擎:以统一的数据结构存储测试结果,包括步骤序列、观察上下文、动作决策链、失败归因等。

共享底座带来的直接好处是:同一个缺陷,无论是计划模式还是探索模式发现的,都能在同一个报告视图里回溯完整过程。我见过太多团队从两种模式发现问题后,需要人工比对半天才能确定是不是同一个 Bug。ARTEMIS 在这一块帮我们省了非常多的时间。

5. 实操落地:ARTEMIS 的配置示例与关键参数

5.1 最小落地配置参考

如果你想在自己的项目中复现 ARTEMIS 的基本框架,可以从最小可用配置开始。下面是我的一个精简版配置片段,YAML 格式,核心参数一目了然:

artemis: modes: controlled: enabled: true max_steps_per_case: 40 state_fingerprint: true loose_match_ratio: 0.85 exploratory: enabled: true max_steps_per_session: 30 cooldown_click_same_element: 3 guardrail_level: medium scheduler: task_type_regression: controlled task_type_exploration: exploratory switch_on_instability_count: 3 switch_on_coverage_stagnation: 5 platforms: - android - ios capture: screenshot: true view_hierarchy: true ocr: true reporting: include_decision_trace: true

这里的loose_match_ratio是我比较得意的一个参数。它表示状态指纹比对时,非关键元素允许匹配的宽容比例。调成 1.0 时,任何细微差异都会导致失败,适合对 UI 精准度要求极高的场景。调到 0.7 时,则允许页面加载出一些额外的推荐内容,适合内容型应用。我建议大多数团队从 0.85 起步,之后再根据测试结果微调。

5.2 调度器模式切换阈值的整定方法

调度器里的switch_on_instability_count和switch_on_coverage_stagnation这两个阈值,需要重点关注。它们控制着模式切换的频率。

我一开始把switch_on_instability_count设为 2,结果计划模式只要遇到一次小弹窗干扰就切换成探索模式,导致测试过程变得碎片化。后来调整为 5,系统表现稳定多了。这里的整定逻辑其实很简单:阈值越小,系统越敏感,适合被测试应用本身质量较差时快速收集信息;阈值越大,系统越稳定,适合被测试应用已经比较成熟时避免无意义的模式切换。

coverage_stagnation阈值指的是探索模式下连续多少次动作没有带来新的页面节点访问,就触发调度器切换到计划模式。这个值我推荐设置在 4 到 6 之间。低于 4 会让模型来不及深入某条路径,高于 6 则会让模型在无效路径上浪费太多时间。

5.3 从纯脚本迁移到双模式时容易踩的三个坑

迁移过程不比从零搭建简单,因为团队习惯和既有资产需要兼顾。

第一个坑是试图把所有旧脚本全部翻译成计划模式的指令序列。旧脚本里很多断言其实是硬编码的界面细节,翻译过去后反而限制了 LLM 的灵活性。我的建议是只迁移核心业务流程,那些零散异常校验场景直接放弃,让探索模式来接管。

第二个坑是忽略感知层的质量。双模式对感知层的要求比传统框架高得多。截图清晰度、OCR 识别率、控件分类准确度,任何一个点存在短板,都会直接传导到 LLM 的决策准确率上。有一次我们的 OCR 识别把“确认下单”识别成“确认定单”,模型生成的计划就一直找不到合适按钮。所以迁移前一定要花时间评估这三个感知组件的质量基线。

第三个坑是护栏规则设计得太死或者太松。太死会让探索模式什么都不敢做,覆盖率极低;太松又容易出安全事故。我建议用一个灰度策略:先允许护栏全开跑几天,收集系统正常行为基线,然后逐步放开限制,每次放开之后观察失败模式变化。这是一种基于经验的调参过程,不能急于求成。

6. 常见问题与排查技巧实录

6.1 LLM 决策空转与页面状态死循环

这是探索模式最让人头疼的问题。表现为模型像“鬼打墙”一样,在同一页面反复执行点击和滑动,却没有任何状态变化。

排查思路有两个:一是检查历史记忆池是否正常工作。如果记忆池里的历史记录没有被正确存储,模型每次决策时都看不到之前走过的路,自然就以为自己每次都在探索新路径。另一个排查方向是页面状态指纹生成逻辑,如果生成指纹时忽略了部分动态元素,比如时间戳、随机推荐位,系统就会认为页面每次都在变化,导致模型认为“每次点击都有新状态”,从而沉浸在这种虚假反馈里。

我建议在状态指纹生成中增加一个动态元素忽略列表。把这些不影响核心业务判断的组件排除在指纹计算之外。

6.2 计划模式失败率高,但不是应用 Bug 而是定位问题

有时候计划模式跑出来的失败记录,分析到底才发现是 LLM 把两个相似功能的按钮语义理解混淆了。比如“保存草稿”和“保存并发布”两个按钮文案相近,模型生成了错误步骤。

解决这个问题的根本思路是增强感知层的语义区分能力。我在 Prompt 构造时加入了控件上下文信息,不光是控件本身的文案,还包括它的相邻控件、容器标题。这样 LLM 可以通过上下文语境区分出两个按钮的真实含义。另外,我还会在计划生成阶段强制让 LLM 输出“选择该控件的原因”,这一步表面上只是增加一个输出字段,实际上能显著提升模型的注意力精度。

6.3 双模式切换频繁导致测试不可复现

这类问题通常出现在调度参数设置不合理时。模式切换确实会造成测试过程不可复现,因为在不同模式下,动作序列、决策逻辑都不同。

解决方案有两个层面。第一层是控制逻辑:给调度器增加一个最小驻留时间参数,比如切换之后至少保持当前模式 5 分钟不变。第二层是记录逻辑:无论最终测试结果如何,报告里都要明确记录本次测试使用的是哪个模式、在哪些步骤发生了切换、切换触发原因是什么。这样即使结果下次没有复现,也能从决策轨迹中找出差异点。

6.4 探索模式在 Android 上经常遇到权限弹窗干扰

Android 系统的权限弹窗千奇百怪,不同厂商的定制系统还会出现不同类型的授权界面。探索模式在处理这些弹窗时很容易误判,导致点击了错误的按钮。

ARTEMIS 最终采用的方法是维护一个“系统弹窗识别库”,通过屏幕文字特征判断当前是否存在系统级弹窗,并自动执行一键关闭策略。这个识别库需要根据团队常用的测试设备品牌定期更新,不同品牌的弹窗文案和布局风格差异很大。建议在设备池里使用主流品牌的代表机型,减少这部分维护成本。

6.5 成本控制:双模式的 Token 消耗为什么忽高忽低

有团队反馈说,双模式架构的 Token 消耗比单 LLM 调用高了太多。我实测下来发现,真正拉高消耗的往往是感知层的视觉数据,而不是决策推理本身。

优化方向有三个:一是截图尽量裁剪到关键区域再传,避免每次都传整张 1080P 大图;二是 XML 层级树可以做压缩,保留可见节点的关键属性即可,过滤掉大量无用的布局信息;三是可以给探索模式设置“低 Token 模式”,在护栏允许的范围内使用更小的视觉编码器,把决策质量略微降低但成本大幅降低。对于预算有限的团队,这是比较务实的投入产出选择。

写在最后的一点体会

ARTEMIS 这套双模式架构并不是一开始就规划的,而是在一次次翻车中逐渐逼出来的。我最大的心得是:不要迷信 LLM 的全知全能,也不要不信任它的临场判断。把计划制定交给它,把动作执行控制在自己手里,把探索自由交给它,把安全边界焊死在系统里。这两条线看似矛盾,但一旦用调度中枢串起来,产生的效果远比任何单一模式都好。如果你也在做移动端 LLM 自动化测试,希望这套拆解能帮你少踩几个我用真金白银踩过的坑。

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

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

立即咨询