Skip to content

Repository files navigation

Android Midscene Automation

一个面向 Android App 的自动化测试工具,同时支持 Midscene AI 测试和 Appium 组件树录制回放。

支持的测试方式

测试方式 页面入口 工作方式 模型要求 适用场景
Midscene Midscene > 测试脚本生成 / 自动化测试 使用自然语言生成和执行测试脚本,通过多模态模型理解设备画面 必须配置模型 页面元素难以稳定定位、希望使用自然语言快速编写测试
Appium Appium 读取 Android 组件树,按 selector、组件 ID 和流程图录制、回放 不需要配置任何模型 需要稳定、可重复、无模型消耗的传统自动化测试

使用 Midscene 前,请先进入“参数配置”完成 Midscene 模型 配置;需要 AI 生成脚本时,还要配置 脚本优化模型。模型配置不可用时,Midscene 脚本无法正常生成或执行。

Appium 方案完全不依赖大模型,不需要填写 Base URL、API Key、Model Name 等模型参数。使用前只需连接 Android 设备、准备 Android SDK / ADB,并启动 Appium 服务。

环境要求

  • Node.js 18+
  • npm
  • Android SDK / ADB,移动端自动化测试需要
  • Appium 3.x 和 UiAutomator2 Driver,仅 Appium 录制回放方式需要

安装 Appium 相关依赖:

npm install -g appium@3.5.0
appium driver install uiautomator2

使用 Appium 方式前需要运行 appium 启动服务;只使用 Midscene 时不需要安装或启动 Appium。

启动

npx --yes android-midscene-automation@latest

启动后访问:

http://127.0.0.1:5173/

每个测试人员在自己的电脑运行这条命令,后端执行的就是当前电脑上的 adb devices,页面会识别当前电脑连接的手机。

如果 5173 端口被占用,可以指定端口:

npx android-midscene-automation --port 5174

功能文档

源码开发

npm install
npm run dev

Midscene Android 测试和 Appium 测试都不需要 Playwright Chromium。只有运行源码中的 Web E2E 示例时才需要单独安装:

npx playwright install chromium

Playwright 浏览器下载不走 npm registry。下载较慢时,可临时指定镜像:

PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright/ npx playwright install chromium

本地启动

npm run dev

启动后访问 Vite 输出的本机地址。项目默认只监听 127.0.0.1

http://127.0.0.1:5173/

npm run dev 会同时启动前端页面和本地后端 API。后端不是独立进程,而是在 vite.config.ts 中通过 server/http-api.ts 挂载到 Vite dev server 的 Connect middleware。

模型配置

模型配置仅用于 Midscene 和 AI 脚本生成,Appium 录制与回放不读取模型配置。首次使用 Midscene 时进入页面的“参数配置”:

  • 运行配置:可选指定 Android SDK 根目录和 Appium 回放报告目录;留空时使用系统 SDK 与默认 output 目录。
  • Midscene模型:执行测试脚本时使用,支持“自定义提供方”和“使用 Codex”。
  • AI生成脚本模型:根据测试需求生成脚本时使用。

使用 npx android-midscene-automation 启动时,配置会保存到固定的系统用户数据目录:

Windows: %LOCALAPPDATA%\android-midscene-automation\.midscene-app\script-cache.sqlite
macOS: ~/Library/Application Support/android-midscene-automation/.midscene-app/script-cache.sqlite
Linux: ~/.local/share/android-midscene-automation/.midscene-app/script-cache.sqlite

也可以通过 ANDROID_MIDSCENE_DATA_ROOT 指定自定义数据目录。使用 npm run dev 本地开发时,默认仍写入项目根目录。

旧版 config.yamlconfig.json 会在读取后迁移到数据库。当前运行时会优先读取数据库中的模型配置。

Android 自动化

执行移动端脚本前确认设备已连接:

adb devices -l

页面会通过 /api/android-devices 获取设备列表。Midscene 执行时由 @midscene/android 连接设备并运行生成脚本;Appium 执行时使用组件树和已录制的流程,不调用大模型。

如果要走不依赖大模型的 Appium 组件树录制方案,可查看项目的 Appium 录制器使用说明。

如果测试人员需要识别自己电脑上的手机,推荐每个人在自己的电脑本地运行:

npx android-midscene-automation

然后访问自己本机的:

http://localhost:5173/

这样后端执行的是当前电脑上的 adb devices,页面会识别当前电脑连接的手机。

如果要回放 Appium 脚本,本机还需要启动 Appium:

appium

后端说明

本项目的本地后端位于 server/http-api.ts,通过 /api/* 暴露能力,主要包括:

  • 脚本生成:POST /api/generate
  • 脚本保存和列表:POST /api/save-scriptGET /api/scripts
  • 脚本执行和停止:POST /api/run-scriptPOST /api/stop-script
  • 模型配置:GET /api/configPOST /api/config
  • 模型测试和消耗统计:POST /api/test-modelGET /api/model-usage-records
  • Android 设备:GET /api/android-devicesPOST /api/android-device
  • Android 预览和操作:GET /api/android-previewPOST /api/android-tapPOST /api/android-swipePOST /api/android-keyevent
  • App 预设:GET /api/app-presetsPOST /api/save-app-presetPOST /api/delete-app-preset

使用 npx android-midscene-automation 启动时,后端运行态文件默认都在系统用户数据目录下;使用 npm run dev 本地开发时,默认在项目根目录下。可以通过 ANDROID_MIDSCENE_DATA_ROOT 覆盖数据目录:

.midscene-app/                 # SQLite 数据库
.midscene-generated/           # 执行前生成的临时脚本
scripts-output/                # 保存的脚本输出
output/                        # Appium 回放 Markdown 报告(可在运行配置中修改)
midscene_run/                  # Midscene 执行报告和运行产物

Appium 录制器使用说明

本文档说明 Appium 组件树录制器的完整使用方式,包括每个操作按钮的用途、录制方法和示例。

本文档随 npm 包发布,也可以从 README 的“功能文档”直接打开。常见问题请查看 常见问题

使用前准备

1. 连接 Android 设备

adb devices -l

确认设备已连接,并且手机已允许 USB 调试。

2. 启动 Appium

appium

如果没有安装 UiAutomator2 Driver:

appium driver install uiautomator2

3. 启动项目

npx --yes android-midscene-automation@latest

或源码开发:

npm install
npm run dev

打开页面后进入 Appium 菜单。

4. 配置运行路径(可选)

进入“参数配置 > 运行配置”可以设置:

  • Android SDK 路径:填写包含 platform-tools/adb 的 SDK 根目录。留空时依次读取 ANDROID_SDK_ROOTANDROID_HOME、系统常见 SDK 目录和 PATH 中的 ADB。
  • 回放报告目录:填写 Markdown 回放报告的保存目录。支持绝对路径;相对路径以启动命令所在目录为基准。留空时使用启动目录下的 output

回放开始前会检测 Android SDK。检测失败时不会创建 Appium session,回放输出会直接显示需要修正的 SDK 路径。

基本录制流程

  1. 选择设备。
  2. 在“参数配置”中添加预设 App 参数。
  3. 回到 Appium 页面,在“节点与脚本”区域选择预设 App。
  4. 等待设备预览和 App 组件树自动加载;必要时点击“刷新组件树”。
  5. 在设备预览或 App 组件树中选择目标组件。
  6. 在“开始”节点或任意步骤后的“插入操作”中选择要录制的操作。
  7. 在“录制步骤”中检查流程、编辑节点备注并配置判断分支。
  8. 输入脚本名称并保存。
  9. 选择已保存脚本后点击“回放”。

App 包名是必填项,只能从“参数配置”中已经添加的“预设 App 参数”选择,不能手动输入。未选择 App 时不能录制操作。

设备预览与组件树

设备预览

  • 设备预览优先使用 Midscene Playground 的 scrcpy 实时画面,可以直接点击和滑动手机画面。
  • 点击预览中的组件后,组件树会定位并选中对应节点,默认同时显示组件边框。
  • 实时流不可用时会自动使用 ADB 截图轮询,避免两种画面来源相互覆盖。
  • 画面停止更新时,可点击设备预览工具栏中的刷新按钮重新获取画面。

App 组件树

  • 首次进入页面、切换设备、Activity 变化或页面结构变化后,组件树会自动刷新。
  • 自动刷新会尽量保留仍然存在的已选节点。
  • 录制操作、回放和手动刷新期间会暂停自动刷新,结束后自动恢复。
  • 组件树支持横向和纵向滚动;下方“当前 Activity”最多显示三行。
  • 手动点击“刷新组件树”可立即重新抓取当前页面结构。

注意:Appium 回放和组件树抓取都会占用 Android UiAutomation。系统会按设备串行执行,并在连接被抢占时清理残留进程后自动重试一次。

流程图节点

录制步骤以流程图节点展示。

节点类型:

  • 操作:执行点击、输入、滑动、返回等动作。
  • 判断:根据页面状态走“是 / 否”分支。
  • 校验:验证页面是否满足预期。

点击节点可以展开编辑面板,支持修改:

  • 节点名称
  • 备注,例如“登录按钮”“账号输入框”
  • 节点类型
  • 超时时间
  • 输入文本
  • 是否可选
  • selector 和父级上下文 selector
  • 判断节点的指定文本与匹配方式

流程画布支持以下操作:

  • 按住空白区域或节点拖动画布。
  • 按住 Ctrl 并滚动鼠标滚轮,在 50%200% 之间缩放。
  • 点击“放大”打开流程总览;总览中同样可以点击节点编辑。
  • 点击节点后的“插入操作”可在任意步骤中间新增操作。
  • 点击节点右上角删除按钮可移除节点,流程引用会自动修正。
  • 浏览器刷新后会保持当前功能页面和 Appium 工作区 Tab;存在未保存修改时,刷新或关闭页面前会提示保存。

单 Activity 录制规则

每个脚本只允许录制一个 Activity。录制点击后如果检测到 Activity 发生变化,会强制弹出保存提示;保存完成后清空当前流程,并从新 Activity 开始录制新脚本。

加载历史脚本时,如果手机当前 Activity 与脚本入口 Activity 不一致,流程编辑会锁定。此时可执行脚本中的“启动 APP”节点,或插入“系统返回”使页面回到脚本绑定的 Activity;Activity 匹配后自动解除锁定。

操作说明

录制点击

用途:点击某个组件。

操作方法:

  1. 在设备预览或组件树中选择按钮、图标、列表项等组件。
  2. 点击“添加操作”。
  3. 选择“录制点击”。

示例:

点击 登录按钮
点击 添加设备入口
点击 我的 Tab

适用场景:

  • 点击按钮。
  • 点击列表项。
  • 点击页面入口。

注意:

  • 优先使用组件 selector。
  • 如果 Appium 找不到组件,会使用 bounds 坐标兜底。

录制输入

用途:向输入框输入文本。

操作方法:

  1. 选择输入框组件。
  2. 点击“添加操作”。
  3. 选择“录制输入”。
  4. 在弹窗中输入文本。

示例:

输入 账号输入框:test@example.com
输入 密码输入框:123456

适用场景:

  • 账号输入。
  • 密码输入。
  • 搜索框输入。
  • 表单字段输入。

注意:

  • 如果账号框和密码框底层 id 一样,录制器会自动保存父级上下文 selector;回放时会先找父级,再找子输入框。
  • 录制后可以展开节点修改输入内容。

清空输入

用途:清空输入框已有内容。

操作方法:

  1. 选择输入框组件。
  2. 点击“添加操作”。
  3. 选择“清空输入”。

示例:

清空 搜索框
输入 搜索框:摄像机

适用场景:

  • 搜索框重复测试。
  • 输入框默认已有内容。
  • 修改表单字段前先清空。

点击坐标

用途:按当前组件中心坐标点击,不依赖 selector。

操作方法:

  1. 选择目标区域。
  2. 点击“添加操作”。
  3. 选择“点击坐标”。

示例:

点击坐标 540,1680

适用场景:

  • 组件树识别不到的自绘区域。
  • selector 不稳定,但坐标稳定的按钮。

注意:

  • 对分辨率、横竖屏、布局变化敏感。
  • 能用组件点击时,不建议优先用坐标点击。

长按

用途:长按某个组件或坐标。

操作方法:

  1. 选择目标组件。
  2. 点击“添加操作”。
  3. 选择“长按”。

示例:

长按 设备卡片

适用场景:

  • 长按打开菜单。
  • 长按删除列表项。
  • 长按进入编辑模式。

默认长按时间为 800ms,可展开节点修改超时时间。

返回键

用途:执行 Android 返回键。

操作方法:

  1. 点击“添加操作”。
  2. 选择“返回键”。

示例:

点击设备详情
返回键
断言存在 设备列表

适用场景:

  • 从详情页返回列表页。
  • 关闭页面。
  • 关闭系统弹窗或软键盘。

Home 键

用途:执行 Android Home 键。

操作方法:

  1. 点击“添加操作”。
  2. 选择“Home 键”。

示例:

Home 键
启动 App

适用场景:

  • 验证 App 从后台恢复。
  • 回到桌面后重新启动 App。

最近任务

用途:打开 Android 最近任务页面。

操作方法:

  1. 点击“添加操作”。
  2. 选择“最近任务”。

示例:

最近任务
Home 键

适用场景:

  • 验证多任务切换。
  • 验证 App 后台状态。

电源键

用途:发送 Android 电源键。

操作方法:

  1. 点击“添加操作”。
  2. 选择“电源键”。

示例:

电源键
添加延时 1000ms
电源键

适用场景:

  • 锁屏 / 亮屏相关测试。

注意:

  • 不同设备锁屏行为可能不同。
  • 自动化回放时请确认设备不会因锁屏无法继续操作。

滑动

用途:执行上、下、左、右滑动。

操作方法:

  1. 点击“添加操作”。
  2. 选择“滑动”。
  3. 输入方向:

示例:

下滑
断言存在 下一页内容

适用场景:

  • 列表滚动。
  • 页面翻页。
  • 轮播切换。

双指缩放

用途:执行双指放大或缩小。

操作方法:

  1. 点击“添加操作”。
  2. 选择“双指缩放”。
  3. 输入方向:放大缩小

示例:

双指放大
双指缩小

适用场景:

  • 地图缩放。
  • 图片预览缩放。
  • 视频画面缩放。

启动 App

用途:启动当前选择的预设 App。

操作方法:

  1. 先选择预设 App 参数。
  2. 在录制步骤的“开始”节点下点击“插入操作”。
  3. 选择“启动 App”,该操作会作为流程第一步插入。

示例:

启动 App
等待 Activity com.example.MainActivity

适用场景:

  • 脚本第一步启动目标 App。
  • 从桌面或其他 App 回到目标 App。

“启动 APP”只能从开始节点添加,并且每个脚本只能有一个启动节点。添加后菜单中的“启动 App”会自动置灰,删除该节点后恢复可用。启动时会通过 ADB 使用当前预设 App 参数中保存的包名打开应用。

录制时可以点击启动节点上的执行按钮立即启动 App,并刷新当前 Activity。回放前会先检查目标 App 是否已在前台:已经启动时跳过“启动 APP”节点并保留当前页面;通过“连接脚本”进入子脚本时,也会跳过子脚本中的启动节点。

添加延时

用途:等待固定时间。

操作方法:

  1. 点击“添加操作”。
  2. 选择“添加延时”。
  3. 输入毫秒数。

也可以在流程节点后点击“插入延时”。

示例:

点击 登录按钮
添加延时 1000ms
断言存在 首页元素

适用场景:

  • 等动画结束。
  • 等网络请求短暂完成。
  • 等系统弹窗出现。

注意:

  • 优先使用“等待 Activity”“断言存在”等状态等待。
  • 固定延时越多,脚本越慢。

判断存在

用途:判断某个组件或指定文本是否出现,并根据结果走不同分支。它可以用于弹窗,也可以用于按钮、列表项、提示文案等普通页面组件。

操作方法:

  1. 选择目标组件上的稳定元素,例如标题、按钮、列表项或提示文案。
  2. 点击“添加操作”。
  3. 选择“判断存在”。
  4. 点击判断节点,按需填写“指定文本”。
  5. 选择“模糊匹配(包含)”或“精准匹配(完全一致)”。
  6. 在“是”或“否”分支下点击“插入操作”,分别添加分支步骤。
  7. 如果两个分支后续要执行相同操作,可以复制公共节点到对应分支,或把公共流程拆成“连接脚本”复用。

示例:

判断存在 确认按钮
  是 -> 点击 确认按钮
  否 -> 不添加操作

分支说明:

  • 未配置指定文本时,只判断目标组件是否存在。
  • 配置指定文本后,会同时检查组件及其子节点文本。
  • 模糊匹配会忽略换行和连续空白差异,只要规范化后的文本包含目标内容即可。
  • 精准匹配要求 Appium 返回的完整文本与指定文本完全一致。
  • 分支可以包含多个连续步骤,也可以在分支末尾连接其他脚本。

适用场景:

  • 首次启动确认弹窗。
  • 权限说明弹窗。
  • 活动弹窗。
  • 只出现一次的引导弹窗。

判断同组件不同内容弹窗

用途:同一个页面有两个弹窗复用同一个组件,只是标题或正文不同,需要按文案区分弹窗类型。

操作方法:

  1. 选择能覆盖弹窗正文的节点;如果文本位于子节点中,也可以选择其稳定父容器。
  2. 点击“添加操作”。
  3. 选择“判断存在”。
  4. 展开节点,在“指定文本”中输入该弹窗特有的文案。
  5. 根据需要选择模糊匹配或精准匹配。
  6. 在“是”分支添加该弹窗对应的确认、取消或关闭步骤;“否”分支继续下一个判断或不添加操作。

示例:

判断存在:指定文本“是否删除设备”
  是 -> 点击 确定
  否 -> 判断存在:指定文本“是否退出登录”
        是 -> 点击 确定
        否 -> 不添加操作

适用场景:

  • 两个弹窗 resource-id、按钮 id、class 都一样。
  • 同一个弹窗组件展示不同业务文案。
  • 需要根据弹窗内容执行不同分支。

注意:

  • 弹窗不是必出现时,先用“判断存在”形成分支,不要直接使用“断言文本”,否则弹窗未出现会让回放失败。
  • 不要只判断“确定”按钮是否存在,这会把两个弹窗都识别成同一种弹窗。
  • 优先用弹窗标题、正文、关键提示文案作为判断目标。
  • 节点详情里的 selector 会显示当前 Activity,方便确认该定位属于哪个页面。

存在则点击

用途:元素出现时点击,不出现时跳过。

操作方法:

  1. 选择可能出现的按钮,例如权限确认、协议同意、活动关闭。
  2. 点击“添加操作”。
  3. 选择“存在则点击”。

示例:

存在则点击 同意按钮
存在则点击 关闭活动弹窗

适用场景:

  • 一次性弹窗。
  • 偶尔出现的活动弹窗。
  • 首次启动协议确认。

存在则输入

用途:输入框出现时输入文本,不出现时跳过。

操作方法:

  1. 选择可能出现的输入框。
  2. 点击“添加操作”。
  3. 选择“存在则输入”。
  4. 在居中弹窗中输入文本。

示例:

存在则输入 搜索框:摄像机

录制后可展开节点修改输入内容。

存在则清空

用途:输入框出现时清空,不出现时跳过。

示例:

存在则清空 搜索框
存在则输入 搜索框:摄像机

存在则返回

用途:某个遮挡元素或页面出现时执行返回键,不出现时跳过。

示例:

存在则返回 权限说明页
存在则返回 引导页

适用场景:

  • 临时引导页。
  • 偶尔出现的中间页。
  • 可通过系统返回关闭的遮挡页面。

等待出现

用途:等待页面加载到某个目标状态。

操作方法:

  1. 选择目标页面的稳定元素。
  2. 点击“添加操作”。
  3. 选择“等待出现”。

示例:

点击 登录按钮
等待出现 首页设备列表

适用场景:

  • 页面跳转后等待目标元素出现。
  • 单 Activity App 无法通过 Activity 判断页面时。

断言存在

用途:校验页面上必须存在某个组件。

操作方法:

  1. 选择目标组件。
  2. 点击“添加操作”。
  3. 选择“断言存在”。

示例:

断言存在 首页设备列表
断言存在 登录失败提示

适用场景:

  • 校验登录成功。
  • 校验页面跳转成功。
  • 校验按钮或列表存在。

注意:

  • 断言失败表示测试失败。
  • 不建议用于可有可无的弹窗。

断言文本

用途:校验组件文本是否包含指定内容。

操作方法:

  1. 选择带文本的组件。
  2. 点击“添加操作”。
  3. 选择“断言文本”。
  4. 输入要校验的文本。

示例:

断言文本 登录失败提示:密码错误
断言文本 页面标题:设备

适用场景:

  • 校验错误提示。
  • 校验标题。
  • 校验列表文案。

等待元素消失

用途:等待某个组件从页面上消失。

操作方法:

  1. 选择 loading、弹窗或遮罩组件。
  2. 点击“添加操作”。
  3. 选择“等待元素消失”。

示例:

点击 登录按钮
等待元素消失 loading
断言存在 首页设备列表

适用场景:

  • 等 loading 结束。
  • 等弹窗关闭。
  • 等遮罩消失。

等待 Activity

用途:等待 Android 当前 Activity 切换到指定值。

操作方法:

  1. 点击“添加操作”。
  2. 选择“等待 Activity”。
  3. 输入目标 Activity。

示例:

点击 登录按钮
等待 Activity com.example.MainActivity

适用场景:

  • 点击按钮后进入新页面。
  • 启动 App 后等待首页 Activity。

注意:

  • 有些 App 使用单 Activity 架构,Activity 不会变化,这时应改用“断言存在”判断页面元素。

连接脚本

用途:把一个已保存脚本连接到当前脚本后继续执行。

操作方法:

  1. 先保存被连接的脚本,例如“首页脚本”。
  2. 打开当前脚本,例如“登录脚本”。
  3. 在主流程节点或判断分支下点击“插入操作”。
  4. 选择“连接脚本”,再选择目标脚本。
  5. 保存当前脚本。

校验规则:

  • 主流程中连接脚本:插入点 Activity 优先使用前一步录制的 pageAfter.activity,只允许选择入口 Activity 与插入点一致的脚本。
  • 判断分支中连接脚本:允许选择同一 App 的其他 Activity 脚本,适合登录成功后进入首页等跳转路径。
  • 分支连接在回放时会等待手机进入目标脚本的入口 Activity;页面没有真正跳转时会超时失败,不会提前执行其他页面的步骤。
  • 目标脚本必须属于当前 App,且不能连接当前脚本自身。
  • 脚本互相连接形成循环时,回放会终止并提示循环连接。

示例:

登录脚本:
  输入账号
  输入密码
  点击登录
  连接脚本:首页脚本

首页脚本:
  启动 App
  断言存在 首页元素
  点击设备列表
  断言存在 设备详情

适用场景:

  • 测试人员不知道点击后页面是什么。
  • 登录流程和首页流程由不同人录制。
  • 复用公共前置流程。

回放行为:

  • 不重新创建 Appium session。
  • 子脚本中的“启动 App”节点会自动跳过,不会重新启动 App。
  • 在当前页面状态继续执行目标脚本。
  • 子脚本单独回放时仍会正常执行自己的“启动 App”节点。
  • 如果脚本互相连接形成循环,会终止并提示循环连接。

脚本保存与管理

保存和更新

  • 新脚本需要填写名称并选择预设 App 后保存。
  • 从顶部脚本下拉框或“脚本列表”加载历史脚本后,再次点击“保存”会更新原脚本,不会因为名称相同而报错。
  • 脚本数据只保存流程图 flow_json,其中包含主流程、判断分支、连接关系、节点备注和页面检查点。
  • 已保存脚本加载后会校验当前 Activity;页面不匹配时按“单 Activity 录制规则”锁定编辑。

脚本列表

在“录制与脚本”区域切换到“脚本列表”Tab,可以:

  • 加载脚本:回到“当前录制”继续查看、编辑或回放。
  • 下载脚本:导出包含完整流程的 JSON 文件。
  • 导入脚本:选择此前导出的 JSON 文件;名称重复时自动生成新名称,不覆盖已有脚本。
  • 删除脚本:删除数据库中的已录制脚本。

导入脚本后仍需在本机配置对应的预设 App,并连接可用的 Android 设备。

回放输出与报告

实时日志

点击“回放”后,日志会随着执行过程实时追加,不需要等待整个脚本结束。所有流程统一使用 [节点 N] 编号,常见内容包括:

[节点 1] 开始:启动 APP com.example.app
[节点 1] 结果:APP 已在前台,跳过启动 com.example.app
[节点 1] 完成:启动 APP com.example.app
[节点 2] 判断:是

默认情况下,每次回放会启动一个独立端口的 Appium 服务。回放输出会完整保留该服务的 stdout/stderr,包括 AppiumAndroidUiautomator2DriverADB、请求参数、响应内容和驱动诊断信息,同时保留工具自身记录的请求方法、接口路径、HTTP 状态和耗时。例如:

2026-08-22 13:57:35:756 - [Appium] Welcome to Appium v3.5.0
[AndroidUiautomator2Driver@ec68] Got response with status 200: {...}
[ADB] Running '.../adb -s device-id shell ...'
[Appium] 请求:POST /session
[Appium] 响应:HTTP 200 POST /session(328ms)

完整 Appium 日志可能包含输入值、设备信息和 WebDriver 请求参数。共享 .log 文件前请先检查并清理敏感内容。

如果通过环境变量 APPIUM_SERVER_URL 显式连接外部 Appium 服务,工具无法读取外部进程所在终端的 stdout/stderr,只会保存 WebDriver 请求、响应状态、耗时和错误响应。需要完整服务端日志时,请不要设置该环境变量,让工具为回放自动启动 Appium。

“回放输出”默认只保留最近 80 行的可视高度,避免无限撑长页面。可以使用:

  • 复制:复制当前完整日志。
  • 展开查看:在弹窗中查看完整日志。
  • 清除:清空页面上的回放输出。

回放期间顶部会显示“终止”按钮。点击后会停止后续节点、关闭当前 Appium session,并继续生成本次回放的报告和日志;执行结果标记为“已终止”。

回放报告、日志和截图回放

每次回放结束后,无论成功、失败或手动终止,都会生成 Markdown 报告、纯文本日志和单文件 HTML 截图回放。三个文件使用相同的日期时间和脚本名称:

当前日期时间-脚本名称.md
当前日期时间-脚本名称.log
当前日期时间-脚本名称.html

报告保存到“参数配置 > 运行配置”指定的目录;没有指定时,默认保存在启动命令所在目录的 output 文件夹中,例如:

output/2026-08-21_17-13-42-831-登录流程.md
output/2026-08-21_17-13-42-831-登录流程.log
output/2026-08-21_17-13-42-831-登录流程.html

报告包含:

  • 脚本、App、Activity、设备、执行时间和结果。
  • 每个节点的类型、selector、上下文 selector、输入值、超时、备注和分支配置。
  • 每个节点的实际执行状态与执行信息。
  • 完整回放日志。

.log 文件保存页面中显示的完整回放过程,以及本次托管 Appium 进程未经截断的 stdout/stderr。生成成功后,报告与日志的绝对路径会追加到实时回放输出中;报告位置同时保存到数据库,便于后续追溯。

.html 文件在每个实际执行节点前后采集设备截图,并将截图以 Base64 形式直接嵌入文件。打开后可以:

  • 在左侧查看执行步骤和当前截图对应的脚本、节点、阶段、结果、备注与 selector。
  • 在顶部时间轴查看截图所在的真实执行时间,并点击缩略图或时间轴跳转。
  • 使用“上一帧”“播放”“下一帧”及进度条控制回放;播放进度按实际回放耗时连续推进,不再按固定间隔逐张切换。
  • 在左侧步骤下方展开完整回放日志;日志默认收起。

判断分支、失败和手动终止会保留对应的最后画面。连接脚本中的实际执行节点也会进入同一条截图时间线。HTML 不依赖外部图片目录,可以单独复制和打开。

组合示例

示例 1:登录成功后连接首页脚本

登录脚本:

启动 App
输入 账号
输入 密码
判断存在 用户协议弹窗
  是 -> 点击 同意 -> 点击 登录 -> 判断登录是否成功 -> 连接脚本 首页脚本
  否 -> 点击 登录 -> 判断登录是否成功 -> 连接脚本 首页脚本

首页脚本:

启动 App
断言存在 首页设备列表
点击 添加设备
断言存在 添加设备页面标题

适合场景:

  • 录制登录时不知道登录成功后跳到哪个页面。
  • 首页流程希望独立维护。

示例 2:登录成功 / 失败分支

输入 账号
输入 密码
点击 登录
判断 首页设备列表是否存在
  是 -> 断言存在 首页设备列表
  否 -> 断言文本 登录错误提示

操作方法:

  1. 先录制输入和点击登录。
  2. 选择用于区分登录结果的稳定元素,添加“判断存在”。
  3. 在“是”分支插入首页校验或“连接脚本”。
  4. 在“否”分支插入错误提示断言。
  5. 如果两个分支后续有相同公共步骤,使用批量复制把公共节点复制到对应分支。

示例 3:一次性弹窗

启动 App
判断存在 确认按钮
  是 -> 点击 确认按钮 -> 断言存在 首页
  否 -> 断言存在 首页

适合场景:

  • 只第一次安装后出现的确认弹窗。
  • 老用户不再出现的弹窗。

示例 4:列表滚动查找元素

启动 App
断言存在 列表页标题
上滑
添加延时 500ms
断言存在 目标列表项

如果列表加载慢,可以把固定延时换成目标元素断言。

示例 5:从详情页返回列表页

点击 设备卡片
断言存在 设备详情标题
返回键
断言存在 设备列表

适合场景:

  • 校验页面返回路径。
  • 校验返回后列表仍可见。

推荐录制规范

  • 每个脚本只负责一个清晰场景。
  • 登录、首页、详情页可以拆成多个脚本,用“连接脚本”组合。
  • 每次页面跳转后,添加一个“断言存在”或“等待 Activity”。
  • 弹窗或其他可选组件使用“判断存在”,不要直接写死必点。
  • 坐标点击只作为兜底。
  • 给关键节点填写“登录按钮”“账号输入框”等备注,方便查看流程和报告。
  • 回放失败后优先查看“回放输出”中的失败节点、Activity 和 selector,再打开 output 中的 Markdown 报告查看完整配置。

常见问题

更新后脚本或配置不见了怎么办

通常不是数据被删除,而是旧版本把数据保存到了启动命令所在目录。新版 npx android-midscene-automation 会默认使用固定的系统用户数据目录,并在启动时尝试从当前目录自动迁移旧数据。

默认数据目录:

Windows: %LOCALAPPDATA%\android-midscene-automation
macOS: ~/Library/Application Support/android-midscene-automation
Linux: ~/.local/share/android-midscene-automation

如果迁移后仍看不到旧数据,请在之前启动过的目录里查找 .midscene-app/script-cache.sqlite,再把 .midscene-app 复制到上面的固定数据目录。也可以设置 ANDROID_MIDSCENE_DATA_ROOT 指向原来的数据目录继续使用。

同一个 id 定位到错误输入框怎么办

如果账号框和密码框都是 id/tg_edit,只按 id 回放可能输入到第一个输入框。

建议:

  • 直接分别选择账号框和密码框录制输入。
  • 在节点详情里确认 selector 是否显示“重复 N”,以及“推荐定位”是否显示父级 + 子级。
  • 如果推荐定位不准确,展开录制步骤,手动修改父级上下文 selector。
  • 坐标点击只作为最后兜底。

点击后没有检测到页面跳转怎么办

可能原因:

  • 按钮当前禁用。
  • 账号密码不正确。
  • App 使用单 Activity,Activity 不变化。
  • 页面跳转依赖网络。

推荐:

  • 使用“断言存在”判断下个页面核心元素。
  • 多 Activity 页面可以拆成两个脚本,在判断分支中用“连接脚本”串起来;回放会等待目标 Activity 出现。
  • 单 Activity App 不要依赖 Activity 变化,应使用页面核心元素判断是否已进入目标状态。

为什么连接脚本提示入口 Activity 不匹配

  • 主流程连接要求目标脚本入口 Activity 与当前插入点一致,适合复用同一页面上的公共流程。
  • 登录后进入首页等跨 Activity 场景,应先添加“判断存在”,再在“是”或“否”分支中添加“连接脚本”。
  • 分支连接允许选择同一 App 的其他 Activity,但不会主动跳转页面;前面的点击或输入必须真正触发跳转。
  • 如果页面未跳转,回放会在等待目标 Activity 超时后失败,这是为了防止在错误页面执行目标脚本。

为什么在桌面点击 App 后回放无效

部分厂商系统会限制桌面或启动器页面的控件信息,Appium 可能无法获取桌面图标的稳定 id。此时在桌面录制“点击 App 图标”可能无法回放。

建议在开始节点后添加“启动 App”操作,由系统按包名打开目标 App,替代桌面点击图标。需要重置登录态或缓存时,可以先添加“清理 App 缓存”,再添加“启动 App”。

弹窗只出现一次怎么办

使用“判断存在”。

判断存在 确认按钮
  是 -> 点击 确认按钮
  否 -> 不添加操作

不要直接把弹窗确认按钮作为普通必选点击,否则弹窗不出现时脚本会失败。

什么时候用等待 Activity

适合多 Activity App。

如果 App 是单 Activity 架构,优先用:

断言存在 页面核心元素

什么时候用可选步骤

可选步骤适合非主流程阻塞项:

  • 权限弹窗
  • 协议弹窗
  • 活动弹窗
  • 首次引导

不建议把登录按钮、提交按钮、核心断言设置为可选。

回放时出现 UiAutomation not connected 怎么办

组件树刷新和 Appium 回放不能同时占用 UiAutomation。当前版本会在回放期间暂停组件树自动刷新,并在断开时清理残留抓取进程后重试一次。

如果仍然失败:

  1. 确认手机保持解锁,USB 调试授权没有失效。
  2. 确认 Appium 和 UiAutomator2 Driver 已正常启动。
  3. 停止其他正在抓取同一设备组件树的工具。
  4. 重新连接设备后再次回放。

设备预览或组件树没有更新怎么办

  1. 先确认设备仍显示在设备下拉框中。
  2. 点击设备预览刷新按钮重新获取画面。
  3. 点击“刷新组件树”重新抓取页面结构。
  4. 回放期间组件树自动刷新会暂停,回放完成后会自动恢复。

项目更新记录

v0.1.29

  • 判断节点新增“合并分支”,支持选择一侧公共流程起点,将两侧后续汇入同一段居中流程;另一侧可保留独有操作或确认删除重复后缀,支持嵌套判断及各类分支,公共节点只执行一次且不随单侧节点删除。
  • 将 Checkbox、RadioButton 判断入口合并为“判断勾选”,新增 Switch 支持;添加和回放时自动校验组件类型及可勾选属性,读取实时 checked 状态进入 true / false 分支,不改变控件状态,兼容已有独立判断节点。
  • “流程控制”新增终止流程节点,执行到该节点时主动结束本次回放,不再执行后续节点或连接脚本;子脚本触发时也结束整个流程,保留执行日志和报告,不作为执行失败。
  • “设备操作”新增启动相册顺序节点,优先解析系统相册入口,必要时查找已安装的常见相册应用;仅打开相册,不选择照片,日志记录实际启动应用,找不到或启动失败时明确报错。
  • Appium 配置新增流程背景色设置,默认沿用浅绿色,支持预选颜色、颜色选择器、#RGB / #RRGGBB 输入校验和恢复默认;保存后持久化,普通画布、放大视图和连接脚本预览统一应用。

v0.1.28

  • Appium 配置中的流程背景色独立成区,与节点模型配置分开展示,保留预选颜色、自定义颜色及保存入口。
  • “组件操作”新增文字点击分支节点,无需预选元素,支持精准匹配和模糊匹配原生组件文字;匹配并点击后进入“匹配到文字”,等待超时未找到则进入“未匹配到文字”。支持编辑文字和超时,多元素匹配及点击异常明确报错,日志和报告保留分支结果。
  • “流程控制”新增输出日志节点,支持设置日志内容和自定义关键字,默认按 stageLog:内容 输出;支持添加后编辑,回放实时输出、日志文件及报告均保留日志内容,多行内容逐行添加关键字。
  • 新增 AI 识别判断节点,可输入按钮可用、画面黑屏等识别要求,通过当前设备截图返回 true / false 并进入对应分支;Appium配置支持独立设置 Base URL、API Key、Model Name 和测试模型,模型需支持图片输入。
  • 长按操作新增元素模式,新建节点默认按元素定位执行长按;添加弹窗和节点配置支持切换元素 / 坐标模式及修改长按时间,旧脚本保留坐标长按行为。
  • 新增原生 Checkbox 和 RadioButton 状态判断节点,添加时校验选中元素类型,回放时读取 checked 属性,按 true / false 进入对应分支,不改变勾选状态;组件详情显示原生勾选属性,回放日志和报告记录判断结果。

v0.1.27

  • npx android-midscene-automation 启动时默认使用固定的系统用户数据目录保存脚本、配置、报告和运行态文件,并在启动时尝试迁移旧版启动目录下的数据,降低升级后脚本或配置“不见了”的风险。
  • 新增脚本列表复制和重命名能力,可直接生成“原文件名 Copy”副本并修改脚本名称,便于复用已有录制流程。
  • 新增检测画面变化能力,支持框选设备预览区域或使用当前选中元素作为检测区域,通过“检测画面变化N-开始节点 / 结束节点”对同一分支内的前后截图进行差异对比。
  • 检测画面变化结果写入 Markdown 和 HTML 回放报告,展示检测区域、阈值、最大变化比例、基准帧、对比帧和差异图,HTML 图片支持点击放大查看。
  • 新增空节点,用于在顺序流程中作为无操作占位节点,配合画面变化检测或流程编排使用。
  • 优化流程图节点插入、删除、复制、缩放和判断分支布局,修复节点新增后连线延迟、缩放后节点不可见、删除检测节点后分支错乱、重复添加同一结束节点等问题。
  • 回放报告截图和截图节点改为使用 ADB 截图,避免 Appium /screenshot 超时后堵塞 UiAutomator2 命令队列;Appium 请求超时时也会显示更准确的超时提示。

v0.1.26

  • 修复流程节点复制与粘贴问题,避免 structuredClone 失败、粘贴后原节点消失、分支插入位置错误和复制后相对位置偏移。
  • 修复判断分支已有节点时入口添加按钮缺失的问题,分支入口现在会保留可插入节点,并正确连接到首个分支节点。
  • 滑动操作支持在添加弹窗和节点配置中修改起点、终点坐标及滑动时长。
  • 长按操作支持设置长按时间,并在节点卡片中显示长按坐标和时长。

v0.1.25

  • Android 设备预览恢复使用 scrcpy 实时流,优化实时流参数,减少 H.264 丢帧导致的花屏;刷新画面时会重启底层 Playground 预览流并等待会话就绪。
  • 测试脚本生成新增提示词模板,可在通用提示词、广告测试、表单填写、聊天对话、播放器测试、搜索列表、订单支付、权限弹窗、个人设置和 H5/WebView 等场景间切换,并支持编辑或上传当前原始 Prompt。
  • 优化 AI 生成流程,支持后台处理和终止生成;生成中锁定原始 Prompt,再次点击“AI 生成”可恢复进度弹窗,终止后不再弹出额外提示。
  • 优化脚本生成提示词策略,区分广告、播放器、弹窗等被测目标与无关遮挡内容,登录流程增加登录后遮挡弹窗处理和无遮挡首页成功判定。

v0.1.24

  • 参数配置的运行配置新增保存校验,Android SDK 路径必须包含 platform-tools/adb,回放报告目录必须填写已存在且可写入的绝对路径。
  • Midscene 自定义提供方的 Model NameModel Family 改为输入框,Base URL 匹配已知提供方时自动填充模型名称和模型系列,并在字段旁新增官方配置说明入口。

v0.1.23

  • 常见问题拆分为独立 FAQ.md 文档,并在 README 的“功能文档”中增加跳转入口。

v0.1.22

  • 升级 Midscene 相关依赖到 v1.12.0

v0.1.21

  • 录制步骤流程图升级为独立画布与节点卡片视图,优化节点内容排版、操作图标、选中态、批量复制和还原位置体验。
  • 统一普通流程线、操作按钮连线和判断分支线条样式,按节点实际高度计算连接位置,修复线条颜色不一致、断裂、多余线条、节点重叠和分支错位问题。
  • 优化判断分支布局,统一“是 / 否”分支的 T 形连接样式,避免分支节点堆叠、左右分支连接错乱及多出第三分支。
  • 连接脚本支持只读预览,使用眼睛图标打开预览弹窗,预览内容居中展示,修改仍需加载脚本后进行。
  • 连接脚本回放时会跳过子脚本开始后的重复“启动 App”和“清除 App”操作,减少跨脚本连接时的重复初始化。
  • 移除“连接到下一节点”“取消连接”“继续主流程”等冗余连接操作,保留复制节点作为主要复用方式。
  • 修复放大面板后点击操作按钮或节点配置会重置缩放的问题,保持当前画布大小和位置。

v0.1.20

  • Appium 流程支持单节点、连续节点及完整判断子流程的复制与粘贴。
  • 优化判断分支布局和流程总览,支持在总览中编辑完整流程。
  • Appium session 与“启动 APP”节点解耦,并避免将桌面、设置等系统 Activity 误识别为脚本入口。
  • 修复复杂判断脚本加载失败及加载后无法进入“当前录制”的问题。

v0.1.19

  • 回放输出支持保留完整 Appium 服务日志,并可在执行过程中手动终止。
  • 新增单文件 HTML 截图回放报告,提供时间轴、步骤导航和连续播放效果。

v0.1.18

  • 使用说明和更新记录自动嵌入 README,可直接在 npm 页面渲染查看。

v0.1.17

  • 新增在线文档查看入口,支持渲染使用说明和更新记录。

v0.1.16

  • 优化参数配置页面布局,将预设 App 参数归入运行配置区域。

v0.1.15

  • README 新增 Midscene 与 Appium 两种测试方式及环境要求说明。
  • 明确 Midscene 需要配置模型,Appium 无需模型即可运行。

v0.1.14

  • 参数配置支持指定 Android SDK 和回放报告目录,并在回放前检查 Android SDK。
  • 回放完成后生成包含节点配置、执行结果和日志的 Markdown 报告。
  • 脚本列表支持 JSON 脚本导入和下载。
  • 设备预览接入 scrcpy 实时画面,组件树可随页面和 Activity 变化自动刷新。
  • 回放输出改为实时流式日志,并增强 UIAutomator 并发和异常恢复能力。
  • 判断分支支持文本匹配、连接不同 Activity 的脚本及连接后的主流程回放。
  • 新增节点备注、未保存提醒和页面状态持久化。

v0.1.13

  • 修复历史脚本新增节点后无法覆盖保存的问题。
  • 修复连接脚本未按顺序继续执行的问题。

v0.1.12

  • “启动 APP”统一为流程开始节点操作,每个脚本最多添加一次。
  • 连接脚本回放时自动跳过子脚本的重复启动操作。

v0.1.11

  • 修复 npm 页面中的更新记录访问链接。

v0.1.10

  • npm 包新增项目更新记录,并清理未随包发布的内部文档链接。

v0.1.9

  • 录制步骤升级为可拖动、缩放和编辑的流程图,支持“是 / 否”判断分支。
  • 支持在流程任意位置插入操作,并编辑节点、定位器、超时和输入内容。
  • 支持 Activity 跳转检测和单 Activity 脚本录制保护。
  • 支持连接已保存脚本,组合登录、首页等跨页面测试流程。
  • 新增脚本管理列表,可加载、删除和回放已录制脚本。

v0.1.8

  • 新增 selector 唯一性检测和父级上下文定位,解决多个组件共用同一 ID 的问题。
  • 回放支持多级定位和坐标兜底,并记录页面检查点与完整失败诊断信息。

v0.1.7

  • 新增存在则点击、输入、清空、返回等可选操作。
  • 新增等待出现、判断存在和等待消失等等待与判断能力。

v0.1.6

  • 新增可复用设备预览,支持点击画面选择组件树节点和刷新实时画面。
  • 组件树支持滚动浏览并展示当前 Activity。
  • 录制操作统一通过“添加操作”菜单选择。

v0.1.5

  • 首次提供 Appium 无模型录制与回放能力。
  • 支持从组件树录制点击、输入、断言和延时,并保存为可回放脚本。
  • App 包名与参数配置中的预设 App 统一管理。

About

一个面向 Android App 的自动化测试工具,同时支持 Midscene AI 测试和 Appium 组件树录制回放。

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages