Midscene iOS 自动化测试 — 完整指南

一、产品概述

项目 说明
产品名称 Midscene.js
厂商 字节跳动 Web Infra 团队(开源)
官网 midscenejs.com
GitHub github.com/web-infra-dev/midscene
核心原理 Vision-Driven(纯视觉驱动)--- 基于截图 + AI 多模态模型实现 UI 操作
协议 适配 WebDriver 协议(通过 WebDriverAgent 连接 iOS 设备)
License MIT(完全开源免费)
支持技术栈 Native / Flutter / React Native / Lynx 等任意 iOS 应用

二、环境准备

2.1 硬件 & 系统要求

项目 要求
操作系统 macOS(iOS 开发必需)
Xcode 安装 Xcode 和命令行工具
iOS 设备 真机或模拟器(iPhone / iPad)
Node.js ≥ 18.0.0
网络 能够访问 AI 模型 API 服务
WebDriverAgent 版本 需要 >= 7.0.0

2.2 软件依赖安装

复制代码
步骤 1:安装 Node.js

# 推荐使用 nvm 管理 Node 版本

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash

nvm install 18

nvm use 18

步骤 2:安装 Xcode 命令行工具

xcode-select --install

步骤 3:准备 WebDriverAgent
方式 A:iOS 模拟器(较简单)

# 使用 Appium 提供的预编译 WDA

# 参考:https://appium.github.io/appium-xcuitest-driver/latest/guides/run-prebuilt-wda/


方式 B:真机(需要开发者账号)

# 参考官方文档配置开发者模式:

# https://appium.github.io/appium-xcuitest-driver/latest/getting-started/device-setup/

# 需要配置:

# 1. Apple Developer 账号 + WebDriverAgent Runner target 签名

# 2. 开启开发者模式:设置 → 隐私与安全性 → 开发者模式

# 3. 开启 UI Automation:设置 → 开发者 → UI Automation

# 4. 设备信任 Mac 电脑

步骤 4:验证 WebDriverAgent 连接

# 访问 WebDriverAgent 状态接口(默认端口 8100)

curl http://localhost:8100/status

# 正确响应示例:
{
  "value" : {
    "build" : {
      "version" : "13.2.0",
      "time" : "Jun  7 2026 22:03:27",
      "productBundleIdentifier" : "com.facebook.WebDriverAgentRunner"
    },
    "os" : {
      "testmanagerdVersion" : 65535,
      "name" : "iOS",
      "sdkVersion" : "17.0",
      "version" : "18.7.9"
    },
    "device" : "iphone",
    "ios" : {
      "ip" : "192.168.1.192"
    },
    "message" : "WebDriverAgent is ready to accept commands",
    "state" : "success",
    "ready" : true
  },
  "sessionId" : null
}

2.3 AI 模型配置

Midscene 支持多种视觉语言(VL)模型,配置通过环境变量注入:

方式一:配置环境变量文件 .env

复制代码
# 创建 .env 文件

cat > .env << 'EOF'

# 必选配置

MIDSCENE_MODEL_API_KEY="替换为你的 API Key"

MIDSCENE_MODEL_BASE_URL="https://你的模型服务地址/v1"

MIDSCENE_MODEL_NAME="你的模型名称"

MIDSCENE_MODEL_FAMILY="模型系列"

# 可选:超时配置(毫秒)

MIDSCENE_MODEL_TIMEOUT=180000

EOF

方式二:支持的模型配置示例

模型 配置示例 说明
千问 Qwen2.5-VL MODEL_FAMILY="qwen-vl" 阿里云通义千问
豆包 Doubao-Vision MODEL_FAMILY="doubao-vision" 火山引擎
智谱 GLM-4.6V MODEL_FAMILY="glm-4v" 智谱 AI
Gemini-3-Pro/Flash MODEL_FAMILY="gemini-3" Google Cloud
UI-TARS MODEL_FAMILY="ui-tars" 字节开源模型,火山引擎
GPT-4o / GPT-4.5 MODEL_FAMILY="gpt-4o" OpenAI
Codex App Server BASE_URL="codex://app-server" OAuth 登录,无需 API Key

方式三:通过 Midscene CLI 全局配置

复制代码
# 全局安装 Midscene CLI

npm install -g @midscene/cli

# 配置模型

export MIDSCENE_MODEL_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"

export MIDSCENE_MODEL_API_KEY="your-api-key"

export MIDSCENE_MODEL_NAME="qwen-vl-max"

export MIDSCENE_MODEL_FAMILY="qwen-vl"

三、快速上手

3.1 零代码体验 --- Playground

Playground 是 Midscene 提供的零代码体验工具,最快验证 AI 驱动流程:

复制代码
# 启动 Playground(自动下载)

npx --yes @midscene/ios-playground

场景演示示例:

复制代码
1、打开safari浏览器应用
2、输入百度网址:www.baidu.com
3、搜索框输入关键词:世界杯日程
4、点搜索

执行结果:

启动后界面包含 4 个核心 Tab:

Tab 功能 对应 API
Act AI 自动规划操作步骤 aiAct()
Query 从界面提取 JSON 数据 aiQuery() / aiBoolean() / aiNumber() / aiString()
Assert AI 智能断言验证 aiAssert()
Tap 即时点击操作(无需 AI 规划) aiTap()

💡 提示: Playground 中通过的流程,在脚本中运行保持一致。

3.2 真机端口转发(如需)

真机连接远程 Mac 时需要端口转发:

复制代码
# 安装 iproxy(来自 libimobiledevice)

brew install libimobiledevice

# 端口转发(WDA 默认 8100,MJPEG 9100)

iproxy 8100 8100 YOUR_DEVICE_ID

iproxy 9100 9100 YOUR_DEVICE_ID

windows下端口转发执行命令:

复制代码
# windows下使用go-ios(官网下载:https://github.com/danielpaulus/go-ios)重新建立隧道、端口转发并启动 WDA
ios tunnel start --udid XXX
ios forward 8100 8100 --udid XXXX
ios runwda --bundleid=com.facebook.WebDriverAgentRunner.xctrunner --testrunnerbundleid=com.facebook.WebDriverAgentRunner.xctrunner --xctestconfig=WebDriverAgentRunner.xctest --udid xxxx

四、编写第一个测试脚本

4.1 安装依赖

复制代码
# 创建项目目录

mkdir my-ios-test && cd my-ios-test

npm init -y

# 安装 Midscene iOS SDK

npm install @midscene/ios dotenv --save-dev

4.2 编写脚本示例

复制代码
// demo.ts
import 'dotenv/config'; // 自动加载 .env 环境变量
import {
  IOSDevice,
  IOSAgent,
  agentFromWebDriverAgent,
} from '@midscene/ios';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

await (async () => {
// 方式一:直接创建设备和 Agent
const page = new IOSDevice({
wdaPort: 8100,
wdaHost: 'localhost',
});

// 初始化 Midscene Agent
const agent = new IOSAgent(page, {
aiActionContext:
'If any location, permission, user agreement, etc. popup appears, click agree. If login page appears, close it.',
});
await page.connect();

// 方式二:使用便捷函数(推荐)
// const agent = await agentFromWebDriverAgent({
//   wdaPort: 8100,
//   wdaHost: 'localhost',
//   aiActionContext: 'If any location popup appears, click agree.',
// });

// ✅ 打开 Safari 并访问 eBay
await page.launch('https://ebay.com');
await sleep(3000);

// ✅ AI 自动规划:搜索 "Headphones"
await agent.aiAct('Search for "Headphones"');

// ✅ 等待页面加载
await agent.aiWaitFor('At least one headphone product is displayed');

// ✅ 从页面提取数据
const items = await agent.aiQuery(
'{itemTitle: string, price: Number}[], find product titles and prices in the list',
);
console.log('Headphone products:', items);

// ✅ AI 断言验证
await agent.aiAssert('Multiple headphone products are displayed on the interface');

await page.destroy();
console.log('✅ Test completed successfully');
})();

4.3 运行脚本

复制代码
```bash

# 使用 tsx 运行 TypeScript

npx tsx demo.ts

# 或使用 Midscene CLI(YAML 模式)

midscene /path/to/yaml --headed

4.4 查看测试报告

脚本成功后会输出:

复制代码
Midscene - report file updated: /path/to/report/some_id.html

在浏览器中打开 HTML 文件,可以回放每一步交互、查询与断言的完整过程。

五、核心 API 一览

API 说明 示例
aiAct(description) AI 自动规划并执行操作 await agent.aiAct('Search for "iPhone"')
aiTap(target) 即时点击(无需 AI 规划) await agent.aiTap('登录按钮')
aiQuery(schema, instruction) 从界面提取 JSON 数据 await agent.aiQuery('{price: Number}')
aiBoolean/Number/String() 提取单一类型数据 await agent.aiBoolean('是否存在立即购买按钮')
aiAssert(assertion) AI 智能断言验证 await agent.aiAssert('页面显示登录成功')
aiWaitFor(condition) 等待条件满足 await agent.aiWaitFor('页面加载完成')
page.connect() 连接 iOS 设备 *
page.launch(app) 启动 App 或打开 URL await page.launch('twitter://')
page.destroy() 断开连接 *

六、使用场景举例

场景 1:iOS 原生 App 登录流程自动化

复制代码
// 登录测试场景

await page.launch('twitter://');

await sleep(2000);

// AI 自动填充登录表单

await agent.aiAct('Fill in the phone number field with "13800138000"');

await agent.aiAct('Fill in the password field with "test123456"');

await agent.aiAct('Click the login button');

// AI 断言验证登录成功

await agent.aiAssert('The home page is displayed with user avatar');

场景 2:电商 App 商品搜索与筛选

复制代码
// 打开电商 App

await page.launch('com.example.shopping://');

// AI 操作搜索

await agent.aiAct('Tap on the search box');

await agent.aiAct('Type "wireless headphones" and press search');

// AI 筛选和提取

await agent.aiAct('Filter by "4 stars and above" and "free shipping"');

const products = await agent.aiQuery(

'{name: string, price: Number, rating: Number}[], extract product list',

);

console.log('Filtered products:', products);

场景 3:社交 App 动态发布

复制代码
await page.launch('instagram://');

await agent.aiAct('Tap on the "+" button to create a new post');

await agent.aiAct('Select the first photo from the gallery');

await agent.aiAct('Add caption "Beautiful sunset #travel"');

await agent.aiAct('Click the share button');

await agent.aiAssert('The post is successfully published and visible in the feed');

场景 4:银行 App 转账流程

复制代码
await page.launch('com.example.bank://');

await agent.aiAct('Navigate to the transfer section');

await agent.aiAct('Enter recipient card number "6222021234567890"');

await agent.aiAct('Enter amount "1000" and note "生活费"');

await agent.aiAssert('Confirmation page shows correct recipient and amount');

await agent.aiAct('Enter PIN code "123456" to confirm');

await agent.aiAssert('Transfer is completed successfully with confirmation message');

场景 5:探索式测试 --- AI 全自动遍历页面

复制代码
// AI 自主探索 App 所有功能
await page.launch('com.example.myapp://');
let continueExploration = true;
let step = 0;

while (continueExploration && step < 20) {
  try {
    // AI 决定下一步操作
    await agent.aiAct('Explore any unexplored UI element or navigation');
    await sleep(1000);
    
    // 提取页面信息
    const info = await agent.aiQuery('{screen: string, elements: string[]}');
    console.log(`Step ${step}: ${info.screen}`, info.elements);
    
    step++;
  } catch (e) {
    // 无法继续时停止
    continueExploration = false;
  }
}

七、真机 vs 模拟器对比

特性 真机 模拟器
端口转发 需要 iproxy 不需要
开发者模式 必须手动开启 默认开启
UI Automation 设置 必须手动开启 默认开启
性能 取决于真机硬件 取决于 Mac 性能
传感器/硬件 真实传感器数据 模拟数据
成本 需要真实设备 Xcode 免费提供
适合场景 兼容性测试、真机性能 快速验证、功能测试

八、常见问题排查

问题 解决方案
WebDriverAgent 已连接但无法控制设备 检查开发者模式是否开启、UI Automation 是否开启、设备是否信任 Mac
MJPEG 画面延迟高 启用原生 MJPEG 流:iproxy 9100 9100 YOUR_DEVICE_ID
AI 操作超时 调整 MIDSCENE_MODEL_TIMEOUT(默认 180s)
模型调用失败 检查 API Key、Base URL、模型名称是否正确配置
无法安装 dotenv 确保 Node.js ≥ 18,使用 npm install dotenv --save-dev

九、Midscene vs 传统 iOS 自动化工具对比

维度 **Midscene** Appium / XCTest UIAutomation
元素定位方式 AI 视觉定位(截图) 代码/XPath 定位 代码定位
脚本编写方式 自然语言描述 代码脚本 代码脚本
页面变化适应性 ✅ AI 自动适应 ❌ 需维护元素定位 ❌ 需维护元素定位
多技术栈支持 ✅ Native/Flutter/RN/Lynx ❌ 仅 Native
上手难度 ⭐ 低(零代码) ⭐⭐⭐ 中 ⭐⭐⭐⭐ 高
学习成本 极低
是否开源免费 ✅ MIT ✅ 开源 ✅ 内置
社区活跃度 活跃(字节跳动维护) 成熟 已废弃

💡 总结:

Midscene 的核心优势在于零代码门槛 + AI 视觉驱动,用自然语言描述操作步骤即可驱动 iOS 设备,大幅降低自动化测试的维护成本,特别适合快速验证、探索式测试、跨技术栈 App 等场景。

相关推荐
aovenus2 天前
go-ios 和 Midscene 配合使用指南
midscene·go-ios
aovenus2 天前
开源 iOS 设备自动化工具-go-ios 介绍
go-ios·ios自动化
aovenus14 天前
使用Midscene对安卓应用进行自动化测试
midscene
AITest研究员1 个月前
Midscene 实战:告别 XPath,用自然语言实现 UI 自动化测试
ui自动化测试·midscene
低调小一1 个月前
Midscene.js 原理拆解:它不是“自然语言点按钮”,而是一套会看屏幕的 UI 自动化运行时
人工智能·rnn·架构·大模型·transformer·tdd·midscene
旺财矿工1 个月前
高效搭建:OpenClaw 2.6.6 Windows 11 一键安装教程
人工智能·自动化·ai自动化·openclaw·小龙虾
苏盆栽1 个月前
实战Pi0机器人控制中心:轻松实现机器人智能操控
机器人控制·多模态模型·ai自动化
aovenus2 个月前
Midscene-视觉驱动的 AI UI 自动化工具
midscene
旺财矿工2 个月前
openclaw一键安装包,配置好了大模型可以直接使用
本地部署·ai智能体·数字员工·ai自动化·openclaw·小龙虾