Detox CLI 命令完全指南:从安装到测试编排与框架缓存管理
2026/9/23 14:41:40 网站建设 项目流程
  • 测试
  • 移动开发
  • 质量保障
  • 开发工具

【免费下载链接】Detox

Gray box end-to-end testing and automation framework for mobile apps

项目地址:https://gitcode.com/gh_mirrors/de/Detox
点击查看免费下载

本篇指南以 Detox 官方 CLI 文档(docs/cli/overview.md)为主体,系统讲解 Detox 命令行工具detox的全部命令与选项:安装方式、init/build/test/start等核心命令的用法与底层实现原理、macOS 专属的框架缓存管理命令、设备锁文件重置以及独立服务器run-server的运维细节。读完本文,你将能够独立完成 Detox E2E 测试项目的初始化、测试套件编排、CI 环境参数调优,并在遇到疑难问题时利用DETOX_ARGV_OVERRIDE等逃生舱机制快速定位问题。

一、Detox CLI 是什么:一条命令背后的两层架构

Detox 是一个用于移动应用的灰盒(gray box)端到端测试与自动化框架。它的所有日常操作——初始化项目、构建被测应用、执行测试、管理 iOS 框架缓存——都通过命令行工具detox完成,即:

Detox CLI lets you operate Detox from command line.

从仓库源码看,这条命令实际上由两层组成:

  1. 全局转发层(detox-cli):文件 detox-cli/cli.js 是一个极简的 Node 脚本。安装全局包detox-cli后,detox命令会先找到当前项目node_modules/.bin下的本地 Detox 可执行文件并将其spawn出来,参数原样透传;唯一的特例是当平台为 macOS 且命令为recorder时,会直接寻找node_modules/detox-recorder/DetoxRecorderCLI并转交给它执行。
  2. 本地命令层(detox):文件 detox/local-cli/cli.js 基于yargs构建,通过.commandDir('./')自动加载local-cli目录下的所有命令模块(initteststartrun-serverreset-lock-file等),并开启了boolean-negation(支持--no-start这类取反写法)、populate--(解析--之后的透传参数)等解析配置。

理解这一分层有助于排查问题:全局包只负责“找到并启动本地二进制”,真正解析参数、执行逻辑的永远是你项目里安装的detox包(版本以项目为准)。

二、安装与基本用法

全局安装 CLI 入口(它本身不包含 Detox 核心,只是转发器):

npm install detox-cli --global

随后所有命令遵循统一语法:

detox <command> [options]

两个全局选项适用于任何命令:

选项说明
--version显示版本号
--help显示帮助信息

注意:--help的显示逻辑由 yargs 的.help()统一提供,--version同理;而--之后的参数会被原样透传给下层(详见下文detox test一节)。

三、命令速查表

命令说明
init为 Detox 创建初始 E2E 测试目录结构
build运行指定配置中build属性定义的构建命令
test启动你的测试套件
recorder启动 Detox Recorder 录制(已弃用)
build-framework-cache仅 macOS。~/Library/Detox构建(或重建)缓存的 Detox 框架与 XCUITest-runner。缓存按 Xcode 与 Detox 版本组合区分
clean-framework-cache仅 macOS。删除~/Library/Detox下所有已编译的框架与 XCUITest-runner 二进制,它们会在npm install或运行build-framework-cache时重建
rebuild-framework-cache仅 macOS。清理并重建~/Library/Detox下的框架与 XCUITest-runner 缓存
reset-lock-file完全重置 Detox 锁文件,此后所有设备都被标记为可用
run-server启动一个独立的 Detox 服务器

下文按“初始化与构建 → 测试编排 → 设备与缓存管理 → 服务器”的顺序逐一展开。

四、detox init:一键生成 E2E 测试脚手架

detox init

该命令会在当前项目目录生成三个模板文件,帮助你快速上手 Detox(完整流程可参考 docs/introduction/project-setup.mdx):

  • .detoxrc.js—— Detox 配置文件(详见 docs/config/overview.mdx);
  • e2e/jest.config.js—— Jest 配置(详见 docs/config/testRunner.mdx 中的 Jest 配置一节);
  • e2e/starter.test.js—— 一个简单的测试套件示例。

从源码看(detox/local-cli/init.js),initcreateDetoxConfig()createJestFolderE2E()两个步骤组成:前者写出.detoxrc.js,后者创建e2e目录并写入jest.config.jsstarter.test.js。若目标文件已存在,命令会报错并置退出码为 1,而不会覆盖你已有的配置。

生成的.detoxrc.js默认配置(源自 detox/local-cli/init.js 中createDefaultConfigurations())结构如下,其中testRunner声明了测试运行器为 Jest,apps预置了 iOS/Android 的 debug 与 release 四种构建产物,devices预置了 iOS 模拟器与 Android 真机/模拟器,configurations则把它们两两组合成 6 个可用配置:

/** @type {Detox.DetoxConfig} */ module.exports = { testRunner: { args: { $0: 'jest', config: 'e2e/jest.config.js', }, jest: { setupTimeout: 120000, }, }, apps: { 'ios.debug': { type: 'ios.app', binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/YOUR_APP.app', build: 'xcodebuild -workspace ios/YOUR_APP.xcworkspace -scheme YOUR_APP -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build', }, // ios.release / android.debug / android.release 结构相同,仅路径与构建命令不同 }, devices: { simulator: { type: 'ios.simulator', device: { type: 'iPhone 15' } }, attached: { type: 'android.attached', device: { adbName: '.*' } }, emulator: { type: 'android.emulator', device: { avdName: 'Pixel_3a_API_30_x86' } }, }, configurations: { 'ios.sim.debug': { device: 'simulator', app: 'ios.debug' }, 'ios.sim.release': { device: 'simulator', app: 'ios.release' }, 'android.att.debug': { device: 'attached', app: 'android.debug' }, 'android.att.release': { device: 'attached', app: 'android.release' }, 'android.emu.debug': { device: 'emulator', app: 'android.debug' }, 'android.emu.release': { device: 'emulator', app: 'android.release' }, }, };

生成的e2e/jest.config.js(模板见 detox/local-cli/templates/jest.js)已经接好了 Detox 的 Jest 全局设置、测试环境与报告器:

/** @type {import('@jest/types').Config.InitialOptions} */ module.exports = { rootDir: '..', testMatch: ['<rootDir>/e2e/**/*.test.js'], testTimeout: 120000, maxWorkers: 1, globalSetup: 'detox/runners/jest/globalSetup', globalTeardown: 'detox/runners/jest/globalTeardown', reporters: ['detox/runners/jest/reporter'], testEnvironment: 'detox/runners/jest/testEnvironment', verbose: true, };

e2e/starter.test.js(模板见 detox/local-cli/templates/firstTestContent.js)则给出了一条最小可运行用例:beforeAll启动 App、beforeEach重载 React Native,然后断言欢迎页可见、点击按钮后跳转页面:

describe('Example', () => { beforeAll(async () => { await device.launchApp(); }); beforeEach(async () => { await device.reloadReactNative(); }); it('should have welcome screen', async () => { await expect(element(by.id('welcome'))).toBeVisible(); }); it('should show hello screen after tap', async () => { await element(by.id('hello_button')).tap(); await expect(element(by.text('Hello!!!'))).toBeVisible(); }); });

五、detox build:按配置执行应用构建

detox build [options]

build命令的作用是:运行指定配置中build属性所定义的命令。即在.detoxrc.jsapps.*.build中声明的xcodebuild./gradlew构建指令,会由该命令代为执行。它通常配合-c, --configuration <设备配置>使用,与detox test共用一套配置选择规则(未指定且只有一个配置时自动使用唯一配置)。

六、detox test:测试编排的核心命令

detox test是整个 CLI 中最重要、选项最丰富的命令:

detox test [options] <...testFilePaths>

6.1 工作原理:CLI 参数 → 环境变量 → 第三方测试运行器

大多数情况下,detox test是一个“便捷方法”:它把 CLI 参数转换成环境变量,然后调用(一次或多次,取决于--retries)第三方测试运行器。所有未知的旗标都会被原样转发给底层的测试运行器,例如:

detox test -c ios.debug --showConfig

会被翻译成:

DETOX_CONFIGURATION=ios.debug jest --showConfig

也就是说,Detox CLI 打印出来的这条命令,你可以脱离 Detox CLI 单独拿去跑。这一机制在源码中有明确对应:命令处理流程(detox/local-cli/test.js → detox/local-cli/testCommand/TestRunnerCommand.js)先把参数拆分为“Detox 参数”与“运行器参数”两部分(见 detox/local-cli/testCommand/middlewares.js 的splitArgv),再通过_buildEnvOverride-c-l-a--record-logs等选项映射为DETOX_CONFIGURATIONDETOX_LOGLEVELDETOX_ARTIFACTS_LOCATIONDETOX_RECORD_LOGS等环境变量,最后spawnjest ...子进程。

如果某个选项在“测试运行器”和“detox test”两边重名,你可以在保留的--序列之后显式传给它:

detox test -c ios.debug -- --help ↓ DETOX_CONFIGURATION=ios.debug jest --help

6.2 全部选项详解

选项说明
-C, --config-path <configPath>指定 Detox 配置文件路径。若未提供,detox 会依次搜索.detoxrc[.js]package.json中的detox
-c, --configuration <device config>从已定义配置中选择一个设备配置;若未提供且只有一个配置,detox 会默认使用它
-n, --device-name [name]覆盖配置中指定的设备名。适合用同一套构建产物跑多个设备
-l, --loglevel [value]日志级别:fatal, error, warn, info, verbose, trace(源码 detox/local-cli/testCommand/builder.js 中还额外接受debug
-d, --debug-synchronization <value>自定义一个操作/断言在 Detox 开始查询 App “为什么忙”之前的等待时长。默认情况下,操作超过 10 秒仍未完成时打印 App 状态。源码中false会被折算为0true折算为3000(毫秒)
-a, --artifacts-location <path>产物(日志、截图等)根目录
--record-logs [failing/all/none]每个测试的日志是否保存到产物目录。传failing只保存失败测试的日志。默认值:none
--take-screenshots [manual/failing/all/none]每个测试前后是否截图保存到产物目录。传failing只保存失败测试的截图。默认值:manual
--record-videos [failing/all/none]每个测试的屏幕录像是否保存到产物目录。传failing只保存失败测试的录像。默认值:none
--record-performance [all/none][仅 iOS]每个测试的 Detox Instruments 性能录制是否保存到产物目录。默认值:none
--capture-view-hierarchy [enabled/disabled][仅 iOS]在视图操作出错及调用device.captureViewHierarchy()时捕获*.uihierarchy快照。默认值:disabled
-R, --retries针对失败的测试套件文件重新拉起测试运行器,直到其通过,或最多重试<N>
-r, --reuse复用已安装的 App(不删除重装)以加快运行
-u, --cleanup测试结束后关闭模拟器。适合 CI 脚本,确保 detox 干净退出、无残留
--jest-report-specs[仅 Jest]是否实时逐条输出每个 spec 的日志。默认在多 worker 下关闭
-H, --headless以无头模式启动设备。适合在 CI 上运行
--device-boot-args当 Detox 启动设备(Android 模拟器 / iOS 模拟器)时透传给设备的参数列表。注意:值必须写在等号(=)之后并用引号包裹。示例:--device-boot-args="-http-proxy http://1.1.1.1:8000 -no-snapshot-load"
--app-launch-args每次启动 App 时透传给 App 的自定义参数。同样的“等号 + 引号”注意事项适用。完整说明见 启动参数指南
--start控制 app 配置中的start命令是否执行。默认在测试运行器之前运行。传--start=force忽略start命令的错误继续跑测试;传--no-start完全跳过start命令
--no-color关闭日志输出的颜色
--use-custom-logger使用 Detox 自定义的控制台日志实现来输出 Detox(非设备)日志;关闭后回退到 Node.js / 测试运行器的实现(如 Jest)。默认:true
--gpu[仅 Android]以指定的-gpu [gpu mode]参数启动模拟器。源码中可取值:auto, host, swiftshader_indirect, angle_indirect, guest, off
--force-adb-install[仅 Android]由于adb install在 Android 上存在已知问题,Detox 默认采用另一套 APK 安装方案;设为 true 将禁用该方案并强制使用adb install。该旗标是临时性的,直至 Detox 自身方案稳定。默认:false
--inspect-brk借助 Node 的--inspect-brk旗标调试测试运行器。默认:false
--repl启动 REPL(Read-Eval-Print Loop)交互调试模式;--repl=auto表示测试失败时自动进入 REPL。默认:false
--help显示帮助

关于-a, --artifacts-location的补充说明:如果该路径不以/(或反斜杠)结尾,detox CLI 会在路径后追加一个由“配置名 + 时间戳”组成的子目录(例如artifacts/android.emu.release.2018-06-12 05:52:43Z);以/结尾则说明你不需要子目录。更多细节见 开启产物收集。默认值为artifacts(外加一个子目录)。

源码补充:除上表外,detox/local-cli/testCommand/builder.js 还暴露了--keepLockFile(布尔,保留设备锁文件,映射为DETOX_KEEP_LOCKFILE环境变量)等内部选项,供高级场景使用。

6.3--retries与重跑机制

-R, --retries的实现在 detox/local-cli/testCommand/TestRunnerCommand.js 中:execute()会以1 + retries作为剩余轮数进入循环,每次测试运行器非零退出后,从detox.session.testResults中收集失败的测试文件,过滤掉“永久性失败”(isPermanentFailure),在下一轮用jest <失败文件列表>重新拉起;当bail开启且出现永久失败时立即终止。这一机制让 CI 上偶发的 flaky 用例可以被自动重试,同时避免无意义的全量重跑。

6.4 逃生舱:DETOX_ARGV_OVERRIDE

当你在复杂脚本或失败的 CI 构建(如 TeamCity、Jenkins)里排查 Detox 测试问题时,可以在重新运行前设置DETOX_ARGV_OVERRIDE环境变量,向 Detox 注入额外的 CLI 参数:

> export DETOX_ARGV_OVERRIDE="--forceExit -w 1 --testNamePattern='that hanging test' e2e/sanity/login.test.js" > bash scripts/ci.e2e.sh # ... some output ... > detox test -c ios.sim.release -l verbose --maxWorkers 3 # ... configuration=ios.sim.release ... jest --maxWorkers 1 --forceExit --testNamePattern='that hanging test' e2e/sanity/login.test.js

上例中,DETOX_ARGV_OVERRIDE强制 Detox 以单 worker 模式运行 Jest,并在 1 秒后强制退出(--forceExit),且只跑指定文件中的指定测试。

可以看到,DETOX_ARGV_OVERRIDE的思路与NODE_OPTIONS类似——区别在于它不是用于常规流程,而是用于对“正在失败的 Detox 配置”进行临时性的定向修补,以节省排查时间。其实现位于 detox/local-cli/testCommand/middlewares.js 的applyEnvironmentVariableAddendum,会把环境变量内容按 yargs 规则解析后合并进参数(并打印一个醒目的警告横幅,见 detox/local-cli/testCommand/warnings.js)。

请避免在日常流程中使用它——日常首选仍是.detoxrc.js配置文件。

七、detox start:单独运行应用的 start 脚本

detox start [options]

该命令用于从指定配置中提取 App(们)的start命令并执行(start属性说明见 docs/config/apps.mdx;配置结构见 docs/config/overview.mdx)。典型场景是:在跑测试之前单独启动 Metro 等开发服务器,或验证某条start脚本本身。

选项说明
-C, --config-path <configPath>指定 Detox 配置文件路径。若未提供,Detox 搜索.detoxrc[.js]package.json中的detox
-c, --configuration <device config>选择本地配置以从中提取 app 的start脚本。若未提供且只有一个配置,Detox 会默认使用它
-f, --force忽略start脚本的错误并继续执行
--help显示帮助

示例:

# 只有一个配置时直接运行 detox start # 指定配置(长/短别名) detox start --configuration yourConfiguration detox start -c yourConfiguration # 向 start 脚本透传额外参数 detox start -c yourConfiguration -- --port 8082 # 忽略 start 脚本的错误并继续 detox start -c yourConfiguration --force

从源码看(detox/local-cli/start.js),detox start通过detox.resolveConfig解析配置,收集所有 app 配置中的start字段,包装成AppStartCommand并行执行;若配置中没有任何start命令,会打印一条No "start" commands were found in the app configs.警告。

八、macOS 专属:框架缓存三剑客

这三个命令仅限 macOS,用于管理~/Library/Detox下的 iOS 框架缓存:

8.1 detox build-framework-cache

detox build-framework-cache

构建(或重建)缓存的 Detox 框架与 XCUITest-runner。默认两个组件都会构建,可用--detox--xcuitest旗标选择只构建其中一个:

  • --detox——构建 Detox 注入框架。默认 false(构建两者)。
  • --xcuitest——构建 XCUITest 测试运行器。默认 false(构建两者)。

8.2 detox clean-framework-cache

detox clean-framework-cache

清理缓存的 Detox 框架与 XCUITest-runner,用法与上述对应:

  • --detox——清理 Detox 注入框架。默认 false(清理两者)。
  • --xcuitest——清理 XCUITest 测试运行器。默认 false(清理两者)。

清理后,这些二进制会在下次npm install或运行build-framework-cache时重建。

8.3 detox rebuild-framework-cache

detox rebuild-framework-cache

先清理再重建。等价于依次执行clean-framework-cachebuild-framework-cache,同样支持--detox/--xcuitest定向操作。

8.4 缓存结构原理

Detox 将框架与 XCUITest-runner 的缓存放在~/Library/Detox/ios/*下的独立目录中,目录名是 Xcode 与 Detox 版本组合的哈希。缓存用于加速构建、避免无谓的重复编译:

├── ios │ ├── framework │ │ ├── 197a0586bd006583562a5916c969d158133a8c50 │ │ ├── … │ │ └── eddcc1edeffdb3533a977b73b667e1b7f106c38f │ ├── xcuitest-runner │ │ ├── 197a0586bd006583562a5916c969d158133a8c50 │ │ ├── … │ │ └── eddcc1edeffdb3533a977b73b667e1b7f106c38f │ …

这个 40 位十六进制哈希的生成逻辑在 detox/src/utils/environment.js 的getBuildFolderName中:对Detox 版本号 + xcodebuild -version的拼接结果做 SHA-1。因此,升级 Xcode 或 Detox 版本后会自动落入新的缓存目录;而当你怀疑旧缓存损坏、需要强制重编时,就可以用rebuild-framework-cache(或先cleanbuild)。

对应命令的实现位于 detox/local-cli/utils/frameworkUtils.js:build/clean根据--detox--xcuitest及“是否两者都未指定”来决定操作范围,在非 macOS 平台上直接跳过并提示;构建脚本分别是 detox/scripts/build_local_framework.ios.sh(Detox 框架)与build_local_xcuitest.ios.sh(XCUITest runner)。顺带一提,iOS 构建脚本在机器未安装 Xcode 时会打印警告并跳过,不会让命令失败。

九、detox reset-lock-file:设备锁文件重置

detox reset-lock-file

重置 Detox 锁文件。锁文件记录了设备的“忙/闲”状态,用于确保同一台设备不会被多个 Detox 测试会话同时占用

默认情况下,detox test在启动时会清理锁文件,但只针对已分配给“已死 / 不存在进程”的设备(对应源码 detox/src/devices/allocation/DeviceRegistry.js 中的unregisterZombieDevices,通过 PID 服务判断进程是否存活)。而reset-lock-file不同,它把锁文件完全清空——所有设备都被重新标记为可用。

实现上,该命令(detox/local-cli/reset-lock-file.js)构造一个DeviceRegistry并调用其reset()方法,在独占锁内把状态写回初始空状态;锁文件路径由 detox/src/utils/environment.js 的getDeviceRegistryPath()提供(位于~/Library/Detox/device.registry.json,随应用数据目录而定)。典型使用场景:某次测试会话异常崩溃(例如 CI 机器强制杀进程)后,设备被“僵尸会话”标记为忙,导致后续测试无法分配设备,此时执行一次reset-lock-file即可解除锁定。

十、detox run-server:独立 Detox 服务器

detox run-server [options]

启动一个独立的 Detox 服务器。需要说明的是:该工具主要面向 Detox 原生代码库的贡献者,而非外部日常使用

选项说明
-p, --port [port]端口号(默认:8099
-l, --loglevel [value]日志级别:fatal, error, warn, info, verbose, trace
--no-color关闭彩色日志
--help显示帮助

从源码看(detox/local-cli/run-server.js),命令会对端口做校验(必须是 1–65535 之间的整数,否则抛出DetoxRuntimeError),然后以standalone: true方式创建并open()一个 DetoxServer 实例。

十一、detox recorder:已弃用的录制工具

detox recorder

警告:Detox Recorder 工具已弃用(原因是 Detox 团队人力资源不足)。如果你的项目里安装过 Detox Recorder,该命令会启动一次新的录制会话;未安装时,全局转发层(detox-cli/cli.js)会提示Detox Recorder is not installed in this directory并返回错误码。新项目请勿依赖此功能。

十二、CI 与调试实战建议

把以上命令组合起来,可以得到一套适合 CI 的典型用法:

# 1. 安装依赖(会自动触发 iOS 框架缓存的准备) npm install # 2. 构建被测应用 detox build -c ios.sim.release # 3. 运行测试:无头模式 + 结束后关闭模拟器 + 只录制失败用例 detox test -c ios.sim.release --headless --cleanup --record-videos failing --take-screenshots failing -l verbose

调试排障时的常用组合:

  • 定位同步问题detox test -c ios.debug -d 3000,让 Detox 在操作超过 3 秒时就开始查询 App 为何忙碌(默认阈值 10 秒);
  • 单测文件重试detox test -c ios.debug --retries 2 e2e/sanity/login.test.js,针对失败文件最多重试 2 次;
  • 交互式调试detox test --repl进入 REPL,失败自动进入用--repl=auto--inspect-brk可断点调试测试运行器本身;
  • 产物定位:确认--artifacts-location是否以/结尾,以决定产物是平铺还是按“配置名 + 时间戳”分子目录存放(见 docs/config/artifacts.mdx)。

最后提醒:无论使用哪个命令,遇到参数语义不明时都可以随时运行detox <command> --help查看帮助;而命令的权威定义始终来自项目内安装的 Detox 版本(detox/local-cli/目录下的各命令模块),文档(docs/cli/ 目录)则提供了更完整的背景与说明。

  • 测试
  • 移动开发
  • 质量保障
  • 开发工具

【免费下载链接】Detox

Gray box end-to-end testing and automation framework for mobile apps

项目地址:https://gitcode.com/gh_mirrors/de/Detox
点击查看免费下载

相关推荐

上一篇:Midscene.js技术架构深度解析:基于视觉语言模型的跨平台UI自动化框架
下一篇:如何使用minireset.css提升前端开发效率:实用技巧与最佳实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询