expo-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Expo Testing

Expo 测试

Build, install, and test Expo/React Native apps on iOS simulators and physical devices.
在iOS模拟器和物理设备上构建、安装、测试Expo/React Native应用。

Detect Project Config

检测项目配置

Before doing anything, read the project's config to determine:
  1. Bundle ID — from
    app.config.js
    ,
    app.config.ts
    , or
    app.json
    expo.ios.bundleIdentifier
  2. EAS profiles — from
    eas.json
    → available build profiles (development, preview, production)
  3. Detox config — from
    .detoxrc.js
    or
    detox.config.js
    → test runner, build commands, device configs
  4. Deep link scheme — from
    app.config.js
    expo.scheme
  5. Package manager
    bun.lockb
    → bun,
    pnpm-lock.yaml
    → pnpm,
    yarn.lock
    → yarn, else npm
执行任何操作前,先读取项目配置确认以下信息:
  1. Bundle ID — 从
    app.config.js
    app.config.ts
    app.json
    expo.ios.bundleIdentifier
    字段获取
  2. EAS 构建配置文件 — 从
    eas.json
    获取可用的构建配置(开发、预览、生产)
  3. Detox 配置 — 从
    .detoxrc.js
    detox.config.js
    获取测试运行器、构建命令、设备配置
  4. Deep Link 协议 — 从
    app.config.js
    expo.scheme
    字段获取
  5. 包管理器 — 存在
    bun.lockb
    则为bun,存在
    pnpm-lock.yaml
    则为pnpm,存在
    yarn.lock
    则为yarn,否则为npm

Two Paths

两种操作路径

Path 1: Simulator (default)

路径1:模拟器(默认)

Use for automated testing, TDD loops, and AFK runs.
1. Prebuild (if native code changed)
   npx expo prebuild --platform ios --clean

2. Build for simulator
   xcodebuild -workspace ios/<AppName>.xcworkspace \
     -scheme <AppName> \
     -configuration Debug \
     -sdk iphonesimulator \
     -derivedDataPath ios/build

3. Install on booted simulator
   xcrun simctl install booted ios/build/Build/Products/Debug-iphonesimulator/<AppName>.app

4. Launch
   xcrun simctl launch booted <bundleId>
Auto-rebuild detection: Check if any of these changed since last build:
  • ios/
    directory contents (native modules)
  • package.json
    or lock file (new native dependencies)
  • app.config.js
    /
    app.json
    (config changes)
  • Any file matching
    *.podspec
    or
    Podfile
If none changed, skip prebuild and xcodebuild — just reinstall and launch.
适用于自动化测试、TDD开发流程、挂机运行场景。
1. 预构建(如果原生代码有变更)
   npx expo prebuild --platform ios --clean

2. 为模拟器构建
   xcodebuild -workspace ios/<AppName>.xcworkspace \
     -scheme <AppName> \
     -configuration Debug \
     -sdk iphonesimulator \
     -derivedDataPath ios/build

3. 安装到已启动的模拟器
   xcrun simctl install booted ios/build/Build/Products/Debug-iphonesimulator/<AppName>.app

4. 启动应用
   xcrun simctl launch booted <bundleId>
自动重构建检测:检查上次构建后是否有以下内容发生变更:
  • ios/
    目录内容(原生模块)
  • package.json
    或锁文件(新增原生依赖)
  • app.config.js
    /
    app.json
    (配置变更)
  • 任何匹配
    *.podspec
    Podfile
    的文件
如果以上都没有变更,可以跳过预构建和xcodebuild步骤,直接重新安装并启动应用。

Path 2: Physical Device

路径2:物理设备

Use for manual testing, sharing with others, or testing hardware-specific features.
Local (tethered via USB):
npx expo run:ios --device
Lists connected devices and installs directly.
EAS cloud build (shareable):
1. Build
   eas build --profile preview --platform ios

2. Download and install
   # EAS provides a QR code / install link
   # Or download .ipa and install via Finder/Apple Configurator
Device registration (first time only):
eas device:create
适用于手动测试、分享应用给他人、测试硬件相关特性的场景。
本地(通过USB连接):
npx expo run:ios --device
会列出已连接的设备并直接安装应用。
EAS 云构建(可分享):
1. 构建
   eas build --profile preview --platform ios

2. 下载安装
   # EAS会提供二维码/安装链接
   # 也可以下载.ipa文件后通过Finder/Apple Configurator安装
设备注册(仅首次需要):
eas device:create

Follow the URL to register the device's UDID

跟随指引访问对应URL注册设备的UDID

undefined
undefined

Running Detox Tests

运行Detox测试

After build + install on simulator:
undefined
在模拟器上完成构建+安装后执行:
undefined

Full suite

运行全量测试用例

npx detox test --configuration ios.sim.debug
npx detox test --configuration ios.sim.debug

Specific test file

运行指定测试文件

npx detox test --configuration ios.sim.debug e2e/<testFile>.e2e.ts
npx detox test --configuration ios.sim.debug e2e/<testFile>.e2e.ts

With screenshots on failure (default Detox behavior)

失败时自动截图(Detox默认行为)

Artifacts saved to artifacts/ directory

产物保存在artifacts/目录下


**Before running Detox**, check if the Detox binary needs rebuilding:
npx detox build --configuration ios.sim.debug --if-missing

This skips the build if the binary already exists and is up to date.

**运行Detox前**,检查是否需要重新构建Detox二进制文件:
npx detox build --configuration ios.sim.debug --if-missing
如果二进制文件已存在且是最新版本,该命令会跳过构建步骤。

Best Practices for E2E

端到端测试最佳实践

  • Use
    testID
    props
    on interactive elements for reliable selectors
  • Disable Detox synchronization for screens with animations or timers:
    typescript
    await device.disableSynchronization();
    // interact with animated screen
    await device.enableSynchronization();
  • Deep links for test entry points: If the app has a URL scheme configured (
    expo.scheme
    in app config), you can launch directly to a screen:
    typescript
    await device.openURL({ url: '<scheme>://e2e' });
    If no scheme exists and you need E2E entry points, consider adding one — it lets tests skip onboarding and jump to the screen under test.
  • 给交互元素添加
    testID
    属性
    ,保证选择器的可靠性
  • 针对带动画或定时器的页面关闭Detox同步机制
    typescript
    await device.disableSynchronization();
    // 和带动画的页面交互
    await device.enableSynchronization();
  • 通过Deep Link进入测试入口:如果应用配置了URL scheme(app配置里的
    expo.scheme
    ),可以直接打开指定页面:
    typescript
    await device.openURL({ url: '<scheme>://e2e' });
    如果没有配置scheme且需要端到端测试入口,建议新增一个配置,这样测试可以跳过引导流程直接跳转到待测试页面。

Screenshot Capture

截图捕获

For dogfooding and bug discovery, capture screenshots:
typescript
// In Detox tests
await device.takeScreenshot('descriptive-name');
Screenshots are saved to the Detox artifacts directory (configurable in
.detoxrc.js
). Ensure the artifacts directory is in
.gitignore
.
For manual screenshot capture on simulator:
bash
xcrun simctl io booted screenshot screenshots/<name>.png
Store dogfooding artifacts in
.dogfooding/
(gitignored):
.dogfooding/
  screenshots/
  findings.md
  logs/
内部测试和发现bug时可以捕获截图:
typescript
// 在Detox测试中使用
await device.takeScreenshot('descriptive-name');
截图会保存在Detox产物目录(可在
.detoxrc.js
中配置),请确保该产物目录已加入
.gitignore
在模拟器上手动截图:
bash
xcrun simctl io booted screenshot screenshots/<name>.png
内部测试产物请存放在
.dogfooding/
目录(已加入gitignore):
.dogfooding/
  screenshots/
  findings.md
  logs/

Failure Artifacts

失败产物留存

When tests fail, preserve everything useful for debugging:
  • Screenshots — Detox captures automatically on failure
  • Device logs
    xcrun simctl spawn booted log stream --level error
  • Console output — from the test runner
  • Sentry — check for crash reports if Sentry is configured
测试失败时,留存所有有用的调试信息:
  • 截图 — Detox失败时会自动捕获
  • 设备日志 — 执行
    xcrun simctl spawn booted log stream --level error
    获取
  • 控制台输出 — 来自测试运行器的输出
  • Sentry — 如果配置了Sentry,检查崩溃报告

Parallel Simulator Isolation

并行模拟器隔离

When running multiple swarms/agents overnight that both need simulators, each must use its own:
bash
undefined
当夜间运行多个swarm/agent任务都需要使用模拟器时,每个任务需要使用独立的模拟器:
bash
undefined

Create a named simulator for this agent

为该agent创建命名模拟器

xcrun simctl create "Swarm-1" "iPhone 16"
xcrun simctl create "Swarm-1" "iPhone 16"

Returns a UDID like: 4A2B3C4D-5E6F-7890-ABCD-EF1234567890

会返回类似4A2B3C4D-5E6F-7890-ABCD-EF1234567890的UDID

Boot it

启动模拟器

xcrun simctl boot <UDID>
xcrun simctl boot <UDID>

Build and install targeting that specific simulator

构建并安装到指定模拟器

xcrun simctl install <UDID> ios/build/Build/Products/Debug-iphonesimulator/<AppName>.app xcrun simctl launch <UDID> <bundleId>

For Detox, target a specific device by name in `.detoxrc.js`:

```js
devices: {
  simulator: {
    type: 'ios.simulator',
    device: { type: 'iPhone 16', name: 'Swarm-1' }
  }
}
Cleanup after the run:
bash
xcrun simctl delete <UDID>
xcrun simctl install <UDID> ios/build/Build/Products/Debug-iphonesimulator/<AppName>.app xcrun simctl launch <UDID> <bundleId>

Detox可以在`.detoxrc.js`中按名称指定目标设备:

```js
devices: {
  simulator: {
    type: 'ios.simulator',
    device: { type: 'iPhone 16', name: 'Swarm-1' }
  }
}
运行完成后清理:
bash
xcrun simctl delete <UDID>

Troubleshooting

故障排查

ProblemFix
No bundle URL present
Run
npx expo start
in another terminal first
Build fails after adding package
npx expo prebuild --platform ios --clean
then rebuild
Simulator not found
xcrun simctl list devices available
to find booted device
Detox timeoutIncrease timeout in
.detoxrc.js
, check for missing
testID
EAS build queue slowUse local builds for simulator testing, EAS for device sharing
xcrun simctl install
fails
Check the .app path — Debug vs Release, simulator vs device
问题解决方案
No bundle URL present
先在另一个终端运行
npx expo start
新增包后构建失败先执行
npx expo prebuild --platform ios --clean
再重新构建
找不到模拟器执行
xcrun simctl list devices available
查看已启动的设备
Detox超时
.detoxrc.js
中增加超时时间,检查是否缺失
testID
配置
EAS构建队列等待时间长模拟器测试使用本地构建,EAS仅用于设备分享场景
xcrun simctl install
执行失败
检查.app路径是否正确,确认是Debug还是Release版本、是模拟器还是设备构建产物