Detox是一个用于移动应用gray-box E2E测试的框架,由Wix团队专门为React Native项目创建。与black-box方法不同,Detox可以访问应用的内部状态,从而无需手动超时即可自动同步。根据Wix Engineering, 2026的数据,自动同步相比传统等待可将测试运行时间减少40%。
要点
Detox是一个用于移动应用端到端(E2E)测试的框架,由Wix公司于2017年开发。它专为React Native项目设计,但也支持iOS和Android上的纯原生应用。Detox采用gray-box模型工作,这意味着它可以访问应用的内部机制。
Detox与Appium或Calabash的主要区别在于自动同步功能。框架在执行下一个操作之前会等待动画、网络请求和事件处理完成。这完全消除了Thread.sleep()或waitForElement的需要,这些方法会拖慢测试速度。
Detox支持iOS(通过XCTest和Xcode)和Android(通过Espresso和UI Automator)。对于React Native应用,提供对Fabric和旧架构的完全支持。在iOS上,测试在模拟器上运行;在Android上,在模拟器或真实设备上运行。
Detox架构由三个关键组件组成:Detox CLI、Detox测试运行器和Detox Native Driver。Detox CLI管理应用的构建、安装和测试运行。测试运行器(Jest或Mocha)执行测试场景并通过WebSocket与应用通信。
Gray-box测试意味着Detox通过原生桥接访问应用的内部状态。框架跟踪网络请求、动画、计时器和操作队列。当所有队列为空时——Detox认为应用已准备好进行下一步。
同步基于对应用主线程(main thread)的跟踪。Detox等待所有动画完成、HTTP请求返回响应以及事件处理程序执行完毕。如果测试因无限动画而挂起——可以强制关闭特定代码块的同步。
// 为问题部分关闭同步
await device.disableSynchronization();
// 具有长时间动画的操作
await element(by.id('loader')).swipe('down');
await device.enableSynchronization();
Detox的安装从通过npm或yarn添加包开始。安装后需要创建配置文件.detoxrc.js,其中描述每个平台的构建和运行设置。Detox为iOS使用基于Xcode配置的自有构建类型。
配置包括应用路径(app)、构建器类型(build)、构建参数和设备设置(device)。iOS使用appleSimulator,Android使用androidEmulator。还可以指定启动参数,如模拟器的语言或区域。
// .detoxrc.js — 配置示例
module.exports = {
testRunner: { args: { '$0': 'jest', config: 'e2e/config.json' } },
apps: {
'ios.debug': { type: 'ios.app', build: 'xcodebuild ...' },
'android.debug': { type: 'android.apk', build: 'cd android && ./gradlew ...' }
},
devices: {
simulator: { type: 'ios.simulator', device: { type: 'iPhone 15' } },
emulator: { type: 'android.emulator', device: { avdName: 'Pixel_4_API_34' } }
}
};
配置后可用的命令:detox build — 使用测试标志构建应用,detox test — 运行测试。Detox支持通过--workers标志在多个设备上并行运行。
Detox测试使用JavaScript或TypeScript编写,API基于元素查找(matchers)和操作(actions)。Matchers允许按标识符、文本、类型或屏幕位置查找元素。Actions执行点击、文本输入、滑动和滚动。
典型的测试看起来像一个序列:找到元素→执行操作→检查结果。检查使用expect-API,根据元素的存在、可见性或文本进行匹配。Detox通过集成Jest支持describe/it语法。
describe('Login flow', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should log in with valid credentials', async () => {
await element(by.id('emailInput')).typeText('user@test.com');
await element(by.id('passwordInput')).typeText('password123');
await element(by.id('loginButton')).tap();
await expect(element(by.id('homeScreen'))).toBeVisible();
});
});
Detox支持所有流行的手势:点击、长按、滑动、滚动、捏合、多点触控。滚动可以指定方向、速度和停止位置。这允许测试复杂的场景,如下拉刷新或轮播。
Detox与流行的CI系统良好集成:GitHub Actions、CircleCI、Bitrise和Jenkins。在CI中运行需要配置虚拟模拟器iOS(无GUI)和带硬件加速的Android模拟器。Detox提供工件——屏幕截图和日志——用于分析失败的测试。
为加速CI中的测试运行,建议使用带有--workers标志的分片(并行化)。Detox自动将测试文件分配到多个模拟器。在运行之间缓存应用构建也有助于减少构建时间。
# GitHub Actions — 在iOS上运行Detox
- name: Install Dependencies
run: npm ci
- name: Build Detox App
run: npx detox build --configuration ios.sim
- name: Run Detox Tests
run: npx detox test --configuration ios.sim --workers 2
timeout-minutes: 30
为了稳定快速的E2E测试,建议遵循几个规则。避免sleep()——Detox提供自动同步,显式延迟只会拖慢测试并使其不稳定。如果测试因时序问题失败,首先检查同步是否被关闭。按功能分组测试并独立运行也很有用——这简化了查找失败原因的过程。
Detox提供了几个device方法来管理状态:device.reloadReactNative()重新加载包,device.launchNewApp()使用新参数启动应用,device.sendToHome()最小化应用。device.setURLBlacklist()允许从同步中排除特定的URL,这对分析和长轮询连接很有用。
建议为每个测试创建隔离状态。使用beforeEach通过device.reloadReactNative()重新加载应用。对于需要特定数据的测试,创建工厂或API客户端来在服务器上准备数据。避免测试之间的依赖——每个测试应该独立。
Detox通过web.element()和web.invoke()方法支持WebView测试。与Web元素的交互使用by.web(id、css或className)。重要的是要记住WebView需要额外的加载时间——如果同步不起作用,通过waitFor添加加载等待。
// 在Detox中测试WebView
const webView = web(by.id('webview'));
await webView.element(by.web.cssSelector('#submit-btn')).tap();
const result = await webView.element(
by.web.cssSelector('.result-text')
).getText();
await expect(result).toEqual('Success');
Detox通过detox-image-matching插件支持屏幕截图比较。屏幕截图可以检测视觉回归:元素偏移、颜色错误、图标缺失。为了稳定的屏幕截图,请关闭动画并使用固定的模拟器尺寸。
最常见的Detox问题与同步相关:无限动画、长网络请求或计时器挂起。使用--loglevel trace标志的日志记录显示Detox在等待哪些资源。如果Detox挂起——对问题代码部分使用device.disableSynchronization()。
在iOS模拟器上,Detox需要先通过xcodebuild使用iphonesimulator配置构建应用。常见错误是使用Release方案而不是Debug,这会关闭测试标志。对于Android,确保AVD是使用与应用兼容的API创建的,并且Intel HAXM加速已启用。对于macOS上的CI环境,使用带有macOS运行器的GitHub Actions很方便,其中Xcode和模拟器已经预装。
如果测试因超时频繁失败,请检查:同步是否全局关闭,应用代码中是否使用了未清除的setTimeout或setInterval,以及主线程是否被长时间操作阻塞。有时通过testRunner.args.jest.$.testTimeout增加detoxrc.js中的超时时间会有所帮助。要找到问题部分,请启用Detox跟踪日志记录——它会显示框架当前正在等待哪些资源和计时器。
测试运行后,Detox会创建工件:失败测试的屏幕截图、应用日志和JUnit XML报告。屏幕截图在测试失败时自动生成,有助于直观地识别问题。对于CI,工件上传到云存储,并通过Web界面访问以分析失败原因。
常见问题
Detox使用gray-box方法,可以访问应用的内部状态并自动同步。Appium通过WebDriver采用black-box模型,需要手动等待。Detox对于React Native项目更快、更稳定。
Detox测试使用JavaScript或TypeScript编写。框架与Jest和Mocha作为测试运行器集成。iOS的原生引擎用Swift编写,Android的原生引擎用Kotlin和Java编写。
可以,Detox支持iOS(通过XCTest)和Android(通过Espresso)上的原生应用。然而Detox的主要受众是React Native开发者,因为原生项目有更成熟的解决方案。
Detox提供工件:屏幕截图、应用日志和HTML报告。本地调试使用--loglevel trace标志,CI使用带有云上传功能的自动工件收集器。
这是一个Detox API方法,可以在不重新安装的情况下重新加载React Native应用的JavaScript包。在beforeEach中使用它来在每个测试前将应用状态重置到初始屏幕。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。