momentic-mobile-test

momentic-mobile-test

创建、运行和维护 Momentic 移动端 E2E 测试及模块,支持 Android 和 iOS。使用 Momentic MCP 工具进行实时设备验证,仅在对本地移动 v2 变更高度自信时,直接编辑 v2 YAML。

12Star
0Fork
更新于 2026/7/2
SKILL.md
只读
名称
momentic-mobile-test
描述

创建、运行和维护 Momentic 移动端 E2E 测试及模块,支持 Android 和 iOS。使用 Momentic MCP 工具进行实时设备验证,仅在对本地移动 v2 变更高度自信时,直接编辑 v2 YAML。

Momentic Mobile 背景

执行模型

Momentic Mobile 驱动真实的 Android 模拟器和 iOS 模拟器。测试是结构化移动步骤的有序列表。

  • 交互步骤(如点击、输入、滑动、滚动)使用 AI 将自然语言目标解析为具体的设备操作。
  • 断言可以评估可见屏幕状态、原生层级结构和 WebView 状态(如果可用)。
  • 基于目标的 AI 操作可以执行更广泛的任务,但原生移动步骤更稳定,应优先使用。

缓存与记忆

Momentic 缓存已解析的移动步骤元数据(如原生选择器、XML 节点、可见文本、WebView 状态和坐标),因此大多数运行可避免重复 AI 调用。这对速度至关重要,但缓存过期是一个真实的调试可能性:步骤可能点击到错误的元素。AI 检查也可能使用过去结果的记忆来保持跨运行的一致性;错误的记忆可能导致重复的边界失败。

缓存按 git 元数据(包括分支)限定范围。在受保护分支(包括配置的主分支)上跳过缓存写入,除非使用 --save-cache 强制保存缓存或设置了 CI 环境变量。在受保护分支上仍可进行缓存读取。使用 --disable-cache 完全绕过缓存。

强制刷新行为的方法:

  • 当意图改变时,更改步骤描述/断言;这会更改用于缓存匹配的步骤标识。在 v1 中,拼接更改后的步骤也会创建新的内部 UUID。
  • 对于每次运行都应重新解析的动态目标(如今天的日期或下一个可用时段),使用 --disable-cache
  • 通过使用 --cache-id <CacheId>CacheId 带入拼接,保留良好的预览缓存。
  • 当先前的 AI 记忆现在具有误导性时,更改断言措辞并添加消歧。

时序

Momentic 在目标步骤之前使用智能等待。它等待配置的智能等待超时(默认为 5 秒),让设备状态稳定或目标出现。在此窗口内,不要添加手动等待。对于较慢或更语义化的就绪状态,使用有针对性的元素/屏幕检查、AI 检查或原生等待(仅当测试确实需要固定时间时)。

设置优先级

momentic.config.yaml 设置项目默认值,但许多移动设置可以在测试级别覆盖:平台、默认应用资产渠道/标签、模拟器提供商、本地设备/应用覆盖、语言环境/时区、地理位置、超时、标头和环境。在假设项目默认值适用之前,始终检查测试自身的元数据。

对于托管移动资产,将 momentic_get_artifacts() 中的 channels 视为真实来源。settings.defaultChannel 必须是测试平台的真实渠道。settings.defaultTag 是可选的;省略它以使用该渠道最近上传的标签。不要假设 "latest" 是特殊的,除非该字面标签存在。

测试上下文

每次运行都有一个测试范围的 env 上下文,该上下文在步骤(包括模块)之间持久存在。后续步骤可以读取先前步骤写入的值。

  • v2:在具有返回值的步骤上使用 saveAs
  • v1/MCP CLI 字符串:使用 --env-key
  • JavaScript:优先使用 returnsaveAs / --env-key;在设置多个变量时使用 setVariable(name, value)
  • 在 JavaScript 和模块输入表达式中使用 env.NAME
  • 在字符串字段中使用 {{ env.NAME }}{{ ... }} 可以评估 JavaScript,但不要在 JavaScript 步骤源代码中使用它,因为 env 已在该作用域中。

模块输入是作为字符串的 JavaScript 片段。引用字符串字面量,并使用 env.X 引用变量;它们不是 {{ }} 模板。

JavaScript 上下文

移动 JavaScript 步骤在移动执行沙箱中运行。将它们用于简短的一次性数据准备、API 检查、断言或上下文写入(原生移动步骤无法表达的操作)。

沙箱通常提供 envsetVariableaxiosassert 和其他 Momentic 提供的辅助函数。如果确切的 JS 支持很重要,请查看 JavaScript 命令文档或 momentic_session_start 中的步骤编写指南。

将简短的一次性 JavaScript 内联。在 v2 YAML 中,可重用的实用程序和长脚本可以放在项目脚本文件中,遵循现有项目约定。当项目已有 scripts/ 模式时,优先选择诸如 $MOMENTIC_PROJECT_ROOT/scripts/mobile-utilities/setup.js 的位置。首先阅读附近的脚本,并匹配其模块风格、辅助函数命名、env 使用和错误风格。

磁盘上的项目状态

移动测试是 *.test.yaml 文件。移动模块是可重用的步骤集合,存储为 *.module.yaml 文件。测试 ID 是权威的,位于测试文件的 id 字段上。

有两种主要的移动文件格式:

  • fileType: momentic/mobile-test/v2fileType: momentic/mobile-module/v2 -> 移动 v2。当不需要实时设备发现时,对于高度自信的局部更改,首选直接 YAML 编辑。
  • 缺少 fileType,或任何其他值 -> v1。切勿直接编辑 v1 YAML;仅通过 momentic_test_splice_steps 持久化更改。

移动 v2 测试包含必需的 platform 值:ANDROIDIOS。平台特定的命令可用性很重要。不要将仅 Android 的命令添加到 iOS 测试中。

momentic.config.yaml 是项目根配置。它存储项目默认值,用于代理、AI 功能、模拟器设置、文件 glob、环境、移动资产、缓存行为和高级设置。

移动 v2 步骤可以通过相对路径引用本地文件:

  • 模块调用:module: ./modules/login.module.yaml
  • JavaScript 步骤:javascript: ./scripts/setup.js
  • 文件注入:命令特定的本地文件路径

相对路径从包含步骤的 YAML 文件解析,而不是从项目根目录或导入测试。使用 ./...../...;不要使用绝对路径或 ~。如果移动、重命名或删除引用的文件,请 grep 旧路径并更新每个引用。

v1 YAML 仍应仅通过 MCP 编辑。不要在 v1 YAML 或 MCP CLI 步骤字符串中使用文件支持的 JavaScript;v1 JavaScript 步骤应在 code / --code 中包含可执行代码。仅在移动 v2 YAML 中使用 JavaScript 文件引用。

不要向 v2 YAML 添加内部或自动生成的字段。

编辑前

仅收集所需内容:

  • 测试目标和用户可见的移动成功标准。
  • 平台:Android 或 iOS。
  • 应用来源:托管渠道/标签、本地 APK/.app 或已安装的应用。
  • 提供商:默认为远程;仅当用户明确要求本地模拟器/模拟器时才使用本地。
  • 认证要求和所需的环境变量。
  • 不得运行两次的风险操作:提交、购买、删除、发送、创建。

对于长任务,在编写之前检查附近的移动测试和模块。重用现有模块通常比内联重建常见流程更好。

在长时间运行的检查、从头开始、破坏性操作、本地设备覆盖或编辑共享模块之前询问。

选择工作流

如果用户请求特定工作流,请尊重它,除非不安全或不可能。否则,当文件是 v2、更改是局部的、步骤序列已知且不需要实时设备发现时,使用直接移动 v2 YAML 编辑。好的例子:重新措辞断言、调整目标、更新环境键、修复文件引用或从附近模式插入一个小的已知步骤。

当文件是 v1 或未知、必须发现实时 UI 状态、目标时序不稳定、流程是多步骤且不清晰、更改依赖于平台行为或用户要求交互式构建/验证时,使用 MCP 设备验证工作流。

对于新的移动测试,使用 momentic_test_create;如果工具不可见,请搜索它。它需要 nameplatform 和有效的移动设置。仅在请求时传递文件夹/路径字段。

momentic_session_start 需要现有的 testId;它不会创建测试。

通用编写规则

  • 优先使用自然语言元素描述。仅作为最后手段使用坐标目标,用于 AI 无法看到的情况,例如类似画布的表面、非语义自定义视图、地图、游戏或用户请求的坐标目标。
  • 优先使用原生移动步骤而非 JavaScript。仅当没有原生步骤能表达行为时才使用 JS。
  • 不要在开头添加启动/打开应用步骤,除非测试确实需要切换应用或恢复应用状态。
  • 保持断言最小化且由用户驱动。仅当需要使下一个依赖操作可靠时才添加就绪检查。
  • 在应实质性改变屏幕状态的操作之后,在依赖操作之前添加立即验证。对于确定性文本/状态,优先使用 ELEMENT_CHECKSCREEN_CHECK;对于语义视觉状态,使用 AI_CHECK
  • AI_CHECK 默认是多模态的(截图 + 无障碍/XML 层级结构)。对于仅截图检查,使用其纯视觉形式(assertVisually YAML 键)。当层级结构不可用或不可靠时(例如包含多个页面的 WebView),或条件纯粹是视觉时,使用它。条件必须完全可从当前视口验证,因为没有层级结构和屏幕外内容可用。
  • 除非用户要求或现有测试已使用 AI 操作,否则不要使用 AI 操作。
  • 除非需要正确性,否则不要添加可选/默认字段。
  • 保持差异小。保留不相关的参数、请求体、环境键、字面值、引号、注释、顺序和步骤风格。
  • 不要绕过真实的应用故障。如果应用损坏、数据丢失、权限被阻止、应用资产错误或后端宕机,报告故障而不是削弱测试。
  • 不要重新组织 before / steps / after 或设置/主流程/拆卸,除非测试意图要求。

使用移动 V2 YAML

移动 v2 是人类可编辑的格式。步骤紧凑:每个步骤有一个顶级命令键,例如 tap: Continue,或该键下的详细映射。测试使用 before / steps / after;模块使用 steps。持续时间始终为毫秒。没有可见的步骤/命令 ID。

直接编辑循环:

  1. 确认 fileTypeplatform
  2. 检查附近的测试/模块以了解本地命令风格。
  3. 编辑最小的 YAML 范围。
  4. 当语法或行为不确定时,运行 lint 或 MCP 验证。

常见错误:

  • 在 iOS 测试中使用仅 Android 的命令。
  • 在 v2 YAML 中使用 0..100 之外的百分比坐标,或在 MCP CLI 风格步骤字符串中使用 0..1 之外的坐标。
  • 混淆滑动方向与滚动意图。SCROLL_TO --direction down 搜索下方内容;SWIPE --direction up 向上移动手指并显示下方内容。
  • 向 YAML 添加步骤 ID、命令 ID、缓存 blob 或执行工件。
  • 为命令使用错误的详细目标字段名称。

npx momentic-mobile lint 验证移动 v2 模式和文件引用。当编辑后或移动/重命名引用的文件后不确定语法时,运行它。

磁盘编辑后的状态刷新:

  • 活跃的 MCP 会话:如果可用,使用重新加载,否则重启会话并运行编辑的范围。
  • 没有活跃的 MCP 会话:准备好验证时启动新会话。
  • momentic_test_get 检查持久化状态;它不会在磁盘编辑后刷新活跃会话。

MCP 设备验证工作流

对每个 v1 编辑和需要实时发现的移动 v2 工作使用此工作流。工具表面是共享的;持久化不同:v1 使用拼接,而 v2 可以使用拼接或直接 YAML 编辑加重新加载/重启。

发现

  • momentic_get_artifacts():项目上下文、配置路径、当前工作目录、测试、模块、环境、可用的 AVD、可用的 iOS 模拟器以及托管移动资产渠道。仅读取所需内容。
  • momentic_test_get({ testId | testPath }):检查持久化的移动测试状态。在会话之前,这很有用。在活跃会话中拼接后,优先使用拼接响应或 returnTest: true
  • momentic_module_recommend({ userRequest }):查找可重用的流程。
  • momentic_module_get({ selector }):检查模块参数、默认值、枚举和步骤。选择器恰好是 { id }{ name }{ path } 之一。

会话

  • momentic_session_start({ testId, ... }):启动移动会话。它返回元数据、步骤编写指南工件、带有会话步骤 ID 的活跃测试内容、初始截图和已安装应用信息。必需:testId。单独调用它,不要与其他 MCP 工具并行。
  • 平台从测试推断。优先使用测试的默认模拟器设置。除非用户明确要求,否则省略提供商/设备/应用覆盖。如果必须选择提供商,优先使用 remote;仅在请求时使用 local
  • 会话启动选项包括 providerenvNamelocalDeviceIdlocalAppPath
  • 在构造 CLI 风格移动步骤之前,阅读步骤编写指南。
  • momentic_run_step({ sessionId, fromStep, toStep?, targetSection?, resetSession? }):运行现有的活跃会话步骤。使用来自测试内容或拼接响应的步骤 ID,绝不使用原始 YAML。对于顶级步骤,使用 parentStepIdChain: []
  • 如果状态漂移,使用 momentic_run_stepresetSession: true 在相同的 sessionId 上重启;不要在每次微编辑之间重置。
  • momentic_session_terminate({ sessionId }):完成后终止。

测试编写循环

以检查点大小的块编写 MCP 步骤。预览前进,直到逻辑部分工作,然后拼接该检查点。好的检查点是自然移动流程边界,例如登录完成、权限处理、表单提交、项目创建或确认可见。避免一次拼接一个步骤,除非每个步骤不确定、有风险或影响共享模块结构。

  • momentic_preview_step({ sessionId, step }):执行一个移动步骤而不持久化。它是有状态的。如果返回 CacheId,则在拼接该步骤时包含 --cache-id <CacheId>。响应截图显示步骤后的设备状态。
  • 如果预览截图不足以定位目标,调用 momentic_get_session_state 并设置 returnBrowserState: true,然后检查模拟器状态文本或工件以获取可访问名称、可见文本、XML 节点、webview 结构、屏幕边界和附近结构。
  • 当接下来的几个步骤明显且低风险时(例如填写已知字段),将它们拼接在一起并运行该保存的范围,而不是逐个预览每个字段。
  • momentic_test_splice_steps({ sessionId, startIndex, deleteCount, steps, targetSection?, parentStepIdChain?, returnTest? }):插入、替换或删除步骤并持久化。
  • 拼接后,立即读取响应;它是插入/删除引用和活跃会话步骤 ID 的真实来源。
  • 如果 returnTest: true,在继续之前验证返回的结构。
  • 如果下游步骤仍然存在,运行紧接的下一个步骤或小范围以确认流程仍然连接。
  • 对于非幂等操作(如提交、购买、删除、发送或创建),避免重复预览。预览设置步骤,在风险操作之前拼接检查点,然后仅在验证需要时执行一次风险保存步骤。
  • 对于明显的相邻低风险步骤,批量处理;除非目标或设备状态不确定,否则不要在每次字段后设置检查点。
  • 当请求的编辑完成时,询问是否通过使用 momentic_run_step 运行相关的保存范围来从头验证。

读取工具输出

会话是实时的模拟器/模拟器进程。截图和 UI 快照是临时的。如果操作后截图未显示预期状态,再次调用 momentic_get_session_state;应用可能仍在加载。

MCP 工具可能返回 .momentic-mcp/... 下的工件链接。仅在需要时读取链接的文件:

  • 模拟器状态文本:细化定位或调试原生/webview 结构。
  • 截图:通常已作为图像内联返回。
  • 环境文件:验证 envKey、JavaScript/API 输出或依赖的环境值。
  • 已安装应用报告:当应用启动或安装行为不清晰时,验证包/包状态。
  • momentic_get_session_state 仅在设置 returnBrowserState: true 时返回序列化的模拟器状态;截图默认返回。

CLI 风格步骤字符串

preview_stepsplice_steps 使用 CLI 风格字符串:--step-type <TYPE> [options]。由 momentic_session_start 返回的平台特定步骤编写指南是权威的。

常见示例:

  • 点击:--step-type TAP --description "the Continue button"
  • 输入:--step-type TYPE --description "Email field" --value "user@example.com" --clear-content
  • AI 检查:--step-type AI_CHECK --assertion "the confirmation message is visible" --timeout-seconds 10
  • 滚动到:--step-type SCROLL_TO --description "Settings" --direction down
  • 按键:--step-type PRESS --key HOME
  • 模块:--step-type MODULE --module-id <id> --inputs email=env.USER_EMAIL

拼接示例:

{
  "sessionId": "SESSION_ID",
  "startIndex": 0,
  "deleteCount": 0,
  "steps": [
    "--step-type TAP --description \"the Continue button\" --cache-id UUID_FROM_PREVIEW",
    "--step-type AI_CHECK --assertion \"the next screen is visible\" --timeout-seconds 10"
  ],
  "targetSection": "main"
}

对于移动条件,使用 --assertion-type 和匹配的断言字段创建 CONDITIONAL 步骤,然后使用 parentStepIdChain: [conditionalStepId] 拼接嵌套步骤。

模块

对于 4 步以上的逻辑流程(如登录、权限处理、设置、应用内导航或结账),默认使用模块优先。调用 momentic_module_recommend,使用 momentic_module_get 检查强候选模块,然后决定使用模块还是内联。

模块不能包含模块。在模块内拼接 MODULE 步骤会失败。

编辑共享模块需要用户确认。要通过 MCP 修改模块,将模块步骤替换为携带所需元数据标志的 MODULE 步骤:--parameters--parameter-enum--default-parameter--module-name--module-description--disableddefaultParametersparameterEnums 中的键必须存在于 parameters 中。

模块 inputs 值是作为字符串的 JavaScript 片段。引用字符串字面量,将 env 引用为 env.X,并严格遵循枚举约束。

验证策略

  • 直接移动 v2 编辑且未请求实时验证:总结更改并询问是否运行。
  • 直接移动 v2 编辑且存在活跃会话:如果可用,重新加载,否则重启会话,然后运行编辑的范围。
  • MCP 编写的编辑:预览前进,在逻辑检查点拼接,然后运行下一个下游保存的步骤或范围。
  • 长时间的全测试运行、本地设备覆盖和风险操作需要确认。
  • 完成后终止 MCP 会话。

故障排除

设备状态和时序

  • 错误的屏幕/UI:读取最新的模拟器状态或调用 momentic_get_session_state
  • 截图未更新:再次调用 momentic_get_session_state
  • 不稳定的时序:优先使用 AI_CHECKSCREEN_CHECKELEMENT_CHECK 或有针对性的 SCROLL_TO,而不是通用的 WAIT
  • 长时间的后端作业/导入/上传:使用带有适当超时的断言或屏幕/元素等待,而不是休眠。
  • 权限对话框或系统表单:在继续之前显式处理它。
  • 奇怪的会话状态:使用 momentic_run_step 并设置 resetSession: true

定位和缓存

  • 未找到元素:检查截图/模拟器状态。如果可见,使用可见文本、角色/名称和附近上下文改进描述;如果不存在,调试前置步骤或滚动状态。
  • 快速命中错误元素或没有 AI:怀疑缓存过期,尤其是当屏幕结构与先前运行相似时。
  • 动态目标:更改描述使其稳定,或对该步骤禁用缓存。
  • 坐标:仅当语义定位不可用时使用 --x-fraction / --y-fraction。在 MCP CLI 字符串中,分数为 0..1
  • 滚动方向:使用 SCROLL_TO --direction down 获取下方内容,使用 SCROLL_TO --direction up 获取上方内容。当没有特定目标或 SCROLL_TO 不合适时,使用手动 SWIPE
  • 引用文本:描述中的引用子字符串被 Momentic AI 按字面处理。仅当该确切文本必须出现在屏幕上或元素名称中时使用引号;对于语义匹配,省略引号。

AI 检查性能

  • 模糊的断言:使预期的视觉/文本条件具体化。包括相关的屏幕区域、对象、计数或状态。
  • 字面文本不匹配:引用字符串被视为必须出现在屏幕上的文本。当意图是语义匹配时,移除引号。
  • 屏幕外:视觉条件(如颜色或形状)仅在元素可见时才能评估。使用滚动/手势设置。
  • 重复的错误判断:重新措辞断言,使预期条件更清晰,旧记忆不再适用。
  • 瞬态条件:AI 检查在配置的超时内重试,但每次尝试都是瞬时快照。优先使用稳定的最终状态断言;如有必要,使用确定性元素/屏幕检查。

格式和数据

  • 环境值缺失:确认生成步骤使用了 saveAs / --env-keysetVariable,并且消费语法是 env.X{{ env.X }}
  • 模块输入错误:输入是作为字符串的 JavaScript 片段;引用字符串字面量并严格匹配枚举约束。
  • 应用启动/安装问题:检查测试设置、托管渠道/标签、已安装应用工件以及会话是远程还是本地。
  • 平台不匹配:检查测试 platform 和步骤编写指南中平台特定的命令可用性。

完成检查清单

  • 识别 v1 与移动 v2,并选择 MCP 还是直接编辑。
  • 对于 MCP 更改:预览前进到检查点,使用缓存 ID 拼接,读取拼接引用,并运行下一个保存的步骤/范围。
  • 对于 v2 直接编辑:当语法/行为不确定时,运行 lint 或验证。
  • 除非用户已请求,否则在完整的从头到尾验证之前询问。
  • 结束您启动的任何 MCP 会话。