ios-simulator-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Which tool to use and when

工具选择与适用场景

Two MCP servers are available for iOS testing. They have distinct roles and should not be interchanged:
iOS测试可使用两款MCP服务器,它们的职责不同,不可混用:

XcodeBuildMCP — build, boot, and install

XcodeBuildMCP — 构建、启动与安装

Use XcodeBuildMCP for everything before you start touching the UI:
TaskTool
Check session defaults (project, scheme, simulator)
session_show_defaults
Build and run on simulator
build_run_sim
Build only (no run)
build_sim
List available simulators
list_sims
List schemes in project
list_schemes
Boot a specific simulator
boot_sim
Install a pre-built .app
install_app_sim
Capture logs from simulator
start_sim_log_cap
/
stop_sim_log_cap
Run tests
test_sim
Always call
session_show_defaults
before the first build
in a session to confirm project/scheme/simulator are configured. Never assume defaults are set.
在开始进行UI交互之前的所有操作,都应使用XcodeBuildMCP:
任务工具
检查会话默认配置(项目、Scheme、模拟器)
session_show_defaults
在模拟器上构建并运行
build_run_sim
仅构建(不运行)
build_sim
列出可用模拟器
list_sims
列出项目中的Scheme
list_schemes
启动指定模拟器
boot_sim
安装预构建的.app文件
install_app_sim
捕获模拟器日志
start_sim_log_cap
/
stop_sim_log_cap
运行测试
test_sim
会话中首次构建前务必调用
session_show_defaults
,确认项目/Scheme/模拟器已正确配置,切勿默认认为配置已就绪。

blitz-iphone — interact with the running app

blitz-iphone — 与运行中的应用交互

Use blitz-iphone for everything after the app is running:
TaskTool
Take a screenshot
get_screenshot
Get full UI hierarchy with coordinates
describe_screen
Find tappable elements
scan_ui
Tap, swipe, type, press buttons
device_action
Launch an app by bundle ID
launch_app
List installed apps
list_apps
List connected devices/simulators
list_devices
blitz-iphone is the only tool you should use for UI interaction. Do not use XcodeBuildMCP's UI automation tools (
snapshot_ui
,
tap
) in parallel — they conflict.

应用启动后的所有操作,都应使用blitz-iphone:
任务工具
截图
get_screenshot
获取含坐标的完整UI层级结构
describe_screen
查找可点击元素
scan_ui
点击、滑动、输入、按压按钮
device_action
通过Bundle ID启动应用
launch_app
列出已安装应用
list_apps
列出已连接的设备/模拟器
list_devices
blitz-iphone是唯一适用于UI交互的工具。请勿同时使用XcodeBuildMCP的UI自动化工具(如
snapshot_ui
tap
),否则会产生冲突。

The golden rule: screenshot after every action

黄金准则:每次操作后截图

Never chain multiple actions without taking a screenshot in between.
Every action can have unexpected results:
  • A tap might open a photo viewer instead of selecting a card
  • A swipe might navigate away instead of triggering a gesture
  • A button might be behind a dialog you didn't know appeared
  • An animation might still be in progress
The pattern is always:
action → get_screenshot → verify → next action
If you batch 3-4 actions and something goes wrong, you won't know which one caused it. Screenshots are cheap; debugging blind interactions is not.

切勿连续执行多个操作而不截图
每个操作都可能产生意外结果:
  • 点击可能打开图片查看器而非选中卡片
  • 滑动可能跳转到其他页面而非触发预期手势
  • 按钮可能被未察觉弹出的对话框遮挡
  • 动画可能仍在执行中
正确的流程始终是:
action → get_screenshot → verify → next action
如果你批量执行3-4个操作后出现问题,将无法确定是哪个操作导致的。截图成本很低,但盲目调试交互的成本却很高。

Gesture mechanics

手势操作机制

Swipe length matters

滑动长度至关重要

Short swipes (~100pt) often silently fail on gesture-based UIs (swipeable cards, dismissible sheets, paging views). Always use swipes of 250pt or more for intent-driven gestures:
undefined
在基于手势的UI(如可滑动卡片、可关闭弹窗、分页视图)上,短距离滑动(约100pt)通常会无声失败。对于有明确意图的手势,始终使用250pt及以上的滑动距离
undefined

Too short — may not register

Too short — may not register

fromX: 120, toX: 220 # only 100pt
fromX: 120, toX: 220 # only 100pt

Reliable

Reliable

fromX: 60, toX: 350 # 290pt — always registers

For "swipe left to reject" / "swipe right to accept" card UIs, swipe from near one edge to near the other:
- Pick left: `fromX: 60, toX: 350`
- Reject/remove: `fromX: 350, toX: 50`
fromX: 60, toX: 350 # 290pt — always registers

对于“左滑拒绝”/“右滑接受”的卡片UI,需从靠近一侧边缘滑动至靠近另一侧边缘:
- 选中:`fromX: 60, toX: 350`
- 拒绝/移除:`fromX: 350, toX: 50`

Tapping images opens full-screen viewers

点击图片会打开全屏查看器

In iOS apps with photo/media content, a single tap on an image usually opens a full-screen viewer. If you meant to select it (e.g. for a ranking comparison), you've now opened the viewer instead.
To dismiss a full-screen photo viewer:
  1. Try swipe down:
    fromX: 200, fromY: 400, toX: 200, toY: 800
  2. If that doesn't work, use
    describe_screen
    to find the X/close button and tap it
Do not attempt to use macOS keyboard shortcuts (Cmd+A, Esc) via AppleScript — they don't work on the iOS simulator's UI layer. Use iOS-native gestures only.
在包含图片/媒体内容的iOS应用中,点击图片通常会打开全屏查看器。如果你原本想选中图片(例如用于排名对比),此时会误打开查看器。
关闭全屏图片查看器的方法:
  1. 尝试向下滑动:
    fromX: 200, fromY: 400, toX: 200, toY: 800
  2. 如果此方法无效,使用
    describe_screen
    找到关闭按钮并点击
切勿尝试通过AppleScript使用macOS键盘快捷键(如Cmd+A、Esc)——它们无法作用于iOS模拟器的UI层。仅使用iOS原生手势。

When taps miss

点击未命中时

If a tap doesn't produce the expected result:
  1. Call
    describe_screen
    to get the exact
    AXFrame
    of the target button
  2. Calculate the center:
    x = frame.x + frame.width/2
    ,
    y = frame.y + frame.height/2
  3. Tap that exact coordinate
Don't guess coordinates from screenshots — the accessibility tree gives ground truth.

如果点击未产生预期结果:
  1. 调用
    describe_screen
    获取目标按钮的精确
    AXFrame
  2. 计算中心点:
    x = frame.x + frame.width/2
    y = frame.y + frame.height/2
  3. 点击该精确坐标
不要通过截图猜测坐标——无障碍树会提供准确的真实数据。

First-launch handling

首次启动处理

On a fresh or reset simulator, apps show system dialogs and onboarding that must be dismissed before testing:
  • Notification permission dialogs — tap "Don't Allow" or "Allow" as appropriate for the test
  • Photo library access dialogs — tap "Allow" if the app needs photo access
  • App-specific welcome/onboarding screens — swipe or tap through them
These appear once and won't block subsequent runs on the same simulator, but always check for them at the start of a session.

在全新或重置后的模拟器上,应用会显示系统对话框和引导页面,必须先关闭这些内容才能开始测试:
  • 通知权限对话框 — 根据测试需求点击“不允许”或“允许”
  • 照片库访问对话框 — 如果应用需要访问照片则点击“允许”
  • 应用专属欢迎/引导页面 — 滑动或点击完成引导
这些内容仅在首次启动时出现,不会阻碍同一模拟器上的后续测试运行,但务必在会话开始时检查是否存在这些内容。

Standard test session flow

标准测试会话流程

1. session_show_defaults           # verify project/scheme/simulator
2. build_run_sim                   # build and launch
3. get_screenshot                  # confirm app is running
4. [handle first-launch dialogs]   # dismiss permissions/onboarding
5. get_screenshot                  # confirm main UI is visible
6. [interact with describe_screen + device_action + get_screenshot loop]

1. session_show_defaults           # verify project/scheme/simulator
2. build_run_sim                   # build and launch
3. get_screenshot                  # confirm app is running
4. [handle first-launch dialogs]   # dismiss permissions/onboarding
5. get_screenshot                  # confirm main UI is visible
6. [interact with describe_screen + device_action + get_screenshot loop]

Navigating to the home screen / other apps

返回主屏幕/切换至其他应用

To leave the current app and go to the home screen:
json
{ "action": "button", "params": { "button": "HOME" } }
To open another app (e.g. Photos to verify an export):
  • Press HOME, then use Spotlight search: swipe down on home screen → type app name → tap result
  • Or use
    launch_app
    with the bundle ID if you know it

离开当前应用返回主屏幕:
json
{ "action": "button", "params": { "button": "HOME" } }
打开其他应用(例如打开照片应用验证导出结果):
  • 按下HOME键,然后使用Spotlight搜索:在主屏幕向下滑动 → 输入应用名称 → 点击结果
  • 或者如果你知道应用的Bundle ID,使用
    launch_app
    启动

XCUITest vs agent-driven testing: when to use which

XCUITest与Agent驱动测试:适用场景对比

XcodeBuildMCP's
test_sim
can run XCUITest suites, which is a different mode of UI testing from the interactive blitz-iphone approach. They're complementary — choose based on what you're trying to achieve.
XcodeBuildMCP的
test_sim
可运行XCUITest测试套件,这与blitz-iphone的交互式UI测试模式不同。二者互为补充,需根据测试目标选择使用。

Use
test_sim
+ XCUITest when:

以下场景使用
test_sim
+ XCUITest:

  • The flow is well-defined and repeatable (login, onboarding, form submission)
  • You want regression coverage that runs in CI without an agent
  • Speed matters — XCUITest runs are 5-10x faster than agent-driven interaction
  • The project already has XCUITest infrastructure to build on
  • 流程明确且可重复(如登录、引导、表单提交)
  • 需要可在CI中无需Agent运行的回归测试覆盖
  • 对速度有要求——XCUITest的运行速度比Agent驱动的交互快5-10倍
  • 项目已有XCUITest基础设施可复用

Use blitz-iphone agent-driven testing when:

以下场景使用blitz-iphone Agent驱动测试:

  • You're doing exploratory testing — navigating a complex multi-step flow where the next action depends on what the previous one produced
  • The flow requires visual judgment (does this photo look correctly letterboxed? does this animation feel right?)
  • You're testing a flow that doesn't yet have XCUITest coverage and you want to smoke-test it quickly
  • The flow involves system-level interactions (Photos app, permission dialogs, other apps) that are awkward to script in XCUITest
  • 进行探索性测试——导航复杂的多步骤流程,下一步操作取决于上一步的结果
  • 流程需要视觉判断(如照片是否正确显示为信箱模式?动画效果是否符合预期?)
  • 测试尚未有XCUITest覆盖的流程,且需要快速进行冒烟测试
  • 流程涉及系统级交互(如照片应用、权限对话框、其他应用),这类交互在XCUITest中难以编写脚本

Ideal division of labour

理想的分工方式

  • Write XCUITest for well-defined, high-value paths (authentication, checkout, critical happy paths)
  • Use agent-driven blitz-iphone testing for exploratory sessions, new features before tests exist, and anything requiring visual confirmation
  • After an agent-driven session surfaces issues or validates a flow, that's a good signal to codify it as an XCUITest

  • 为明确的高价值流程(如认证、结账、核心正常流程)编写XCUITest
  • 使用Agent驱动的blitz-iphone测试进行探索性会话、测试未覆盖的新功能,以及任何需要视觉确认的内容
  • Agent驱动测试会话发现问题或验证流程后,可将该流程整理为XCUITest

Mixing interaction styles

混合交互方式

When a UI supports both swipes and button taps (e.g. a card-based keep/remove flow), use both — it exercises more code paths and better simulates real users:
  • Swipe right to keep, swipe left to remove, tap the Keep button, tap the Remove button — alternate between them
  • Don't tap on the card image itself unless you intend to open the full-screen viewer
当UI同时支持滑动和按钮点击时(如基于卡片的保留/移除流程),两种方式都要使用——这样可以覆盖更多代码路径,更真实地模拟用户行为:
  • 右滑保留、左滑移除、点击保留按钮、点击移除按钮——交替使用这些操作
  • 除非你想打开全屏查看器,否则不要点击卡片图片本身