expo-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseExpo 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:
- Bundle ID — from ,
app.config.js, orapp.config.ts→app.jsonexpo.ios.bundleIdentifier - EAS profiles — from → available build profiles (development, preview, production)
eas.json - Detox config — from or
.detoxrc.js→ test runner, build commands, device configsdetox.config.js - Deep link scheme — from →
app.config.jsexpo.scheme - Package manager — → bun,
bun.lockb→ pnpm,pnpm-lock.yaml→ yarn, else npmyarn.lock
执行任何操作前,先读取项目配置确认以下信息:
- Bundle ID — 从、
app.config.js或app.config.ts的app.json字段获取expo.ios.bundleIdentifier - EAS 构建配置文件 — 从获取可用的构建配置(开发、预览、生产)
eas.json - Detox 配置 — 从或
.detoxrc.js获取测试运行器、构建命令、设备配置detox.config.js - Deep Link 协议 — 从的
app.config.js字段获取expo.scheme - 包管理器 — 存在则为bun,存在
bun.lockb则为pnpm,存在pnpm-lock.yaml则为yarn,否则为npmyarn.lock
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:
- directory contents (native modules)
ios/ - or lock file (new native dependencies)
package.json - /
app.config.js(config changes)app.json - Any file matching or
*.podspecPodfile
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 --deviceLists 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 ConfiguratorDevice 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:createFollow the URL to register the device's UDID
跟随指引访问对应URL注册设备的UDID
undefinedundefinedRunning Detox Tests
运行Detox测试
After build + install on simulator:
undefined在模拟器上完成构建+安装后执行:
undefinedFull 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 props on interactive elements for reliable selectors
testID - 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 (in app config), you can launch directly to a screen:
expo.schemeIf no scheme exists and you need E2E entry points, consider adding one — it lets tests skip onboarding and jump to the screen under test.typescriptawait device.openURL({ url: '<scheme>://e2e' });
- 给交互元素添加属性,保证选择器的可靠性
testID - 针对带动画或定时器的页面关闭Detox同步机制:
typescript
await device.disableSynchronization(); // 和带动画的页面交互 await device.enableSynchronization(); - 通过Deep Link进入测试入口:如果应用配置了URL scheme(app配置里的),可以直接打开指定页面:
expo.scheme如果没有配置scheme且需要端到端测试入口,建议新增一个配置,这样测试可以跳过引导流程直接跳转到待测试页面。typescriptawait device.openURL({ url: '<scheme>://e2e' });
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 ). Ensure the artifacts directory is in .
.detoxrc.js.gitignoreFor manual screenshot capture on simulator:
bash
xcrun simctl io booted screenshot screenshots/<name>.pngStore dogfooding artifacts in (gitignored):
.dogfooding/.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内部测试产物请存放在目录(已加入gitignore):
.dogfooding/.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
undefinedCreate 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
故障排查
| Problem | Fix |
|---|---|
| Run |
| Build fails after adding package | |
| Simulator not found | |
| Detox timeout | Increase timeout in |
| EAS build queue slow | Use local builds for simulator testing, EAS for device sharing |
| Check the .app path — Debug vs Release, simulator vs device |
| 问题 | 解决方案 |
|---|---|
| 先在另一个终端运行 |
| 新增包后构建失败 | 先执行 |
| 找不到模拟器 | 执行 |
| Detox超时 | 在 |
| EAS构建队列等待时间长 | 模拟器测试使用本地构建,EAS仅用于设备分享场景 |
| 检查.app路径是否正确,确认是Debug还是Release版本、是模拟器还是设备构建产物 |