
Detox 端到端测试接入 CI 的完整指南Release 构建、模拟器清理与主流 CI 平台配置【免费下载链接】DetoxGray box end-to-end testing and automation framework for mobile apps项目地址: https://gitcode.com/gh_mirrors/de/Detox本文基于仓库中 20.x 版本官方文档 Preparing for CI 编写。该文档在仓库内被明确标注为outdated过时——附录中 Travis 与 Xcode 8.3 等示例偏旧但在 CI 上测试 Release 构建 测试结束后关闭模拟器的核心方法论至今仍然适用。本文将原文档全部实操内容继承下来并结合当前仓库的 CLI 源码、示例配置与 CI 脚本进行纵深解读帮助你以当前仓库的实际情况为准落地一套可靠的 CI 流水线。当移动 App 的端到端测试套件在本地稳定运行后下一步就是把它接入 CI持续集成服务器每次git push自动执行一遍回归测试一旦新改动破坏了既有功能CI 能第一时间发出警报。本文围绕 Detox 官方 CI 准备指南讲解 CI 场景下与本地运行截然不同的两个关键点Release 构建与模拟器清理逐平台给出 Travis CI、Bitrise、GitLab CI 的可直接落地的配置模板并结合仓库源码说明--cleanup、--headless等 CI 常用 CLI 参数的底层行为以及 Android 模拟器环境在无界面 CI 机器上的搭建要点。为什么 CI 上跑 Detox 与本地不同两个关键差异原文档开门见山地指出Running Detox on CI is not that different from running it locally在 CI 上运行 Detox 与本地运行并没有本质区别但存在两个主要差异这也是整套 CI 配置的核心出发点测试 Release 构建而不是 Debug 构建——Release 构建更接近用户最终拿到的产物能捕获仅在优化/混淆后才暴露的问题例如 Android 上 ProGuard 混淆导致的反射失效也更贴近真实性能表现告诉 Detox 在测试结束后关闭模拟器——CI 是批量、反复运行的场景若每次运行都残留一个未关闭的模拟器/模拟器进程会持续占用 CI 机器资源甚至导致后续任务因设备被占用而失败。围绕这两点原文档给出了两个实施步骤并附上了三大 CI 平台的完整配置示例见文末附录。以下逐步展开。Step 1为 App 准备 Release 配置要在 CI 上测试 Release 构建首先需要在 Detox 配置中为 App 准备一个release 形态的 app 配置。如果还没有完成基础的项目接入请先阅读前一篇教程 Project Setup初始化、App/设备配置、构建 App 的全流程。Detox 采用静态配置文件描述apps、devices与configurations三组字典配置名如ios.sim.release就是运行测试时的入口详细结构见 配置总览。仓库自带的端到端测试工程 detox/test/e2e/detox.config.js 就是一份同时覆盖 debug 与 release 的完整示例其中 iOS 的 release 配置形如ios.release: { type: ios.app, name: example, binaryPath: ios/build/Build/Products/Release-iphonesimulator/example.app, build: set -o pipefail export CODE_SIGNING_REQUIREDNO export RCT_NO_LAUNCH_PACKAGERtrue xcodebuild -workspace ios/example.xcworkspace -scheme example-ci -configuration Release -sdk iphonesimulator -derivedDataPath ios/build -quiet, arch: arm64, },几个值得注意的细节binaryPath指向Release 产物Release-iphonesimulator/example.app与 debug 的Debug-iphonesimulator产物路径区分开build命令中export CODE_SIGNING_REQUIREDNO用于模拟器场景跳过签名export RCT_NO_LAUNCH_PACKAGERtrue则避免在 Release 测试时拉起 React Native 打包器Metro——这正是测试 Release 构建的核心语义之一不依赖开发时的打包服务detox build本身没有任何额外逻辑只是把配置里写好的build命令原样执行参见 Project Setup 中的说明因此 CI 上的构建产物与你本地detox build --configuration ios.sim.release完全一致。Android 侧同理仓库示例中定义了android.release见 detox/test/e2e/detox.config.js并通过androidBaseAppConfig(release)生成对应的构建命令与 APK 路径随后在configurations中组合出android.emu.release配置。Android Release 构建还有一个必须处理的坑ProGuard。由于 Detox 在 Android 上依赖 Java 反射 API 与 React Native 集成必须让 Detox 的原生代码豁免于 ProGuard 混淆否则 Release 模式跑测试时会崩溃或无限挂起。在android/app/build.gradle的 release 构建类型中追加详见 Project Setup 的 ProGuard 说明release { minifyEnabled true proguardFiles getDefaultProguardFile(proguard-android.txt), proguard-rules.pro proguardFile ${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro signingConfig signingConfigs.release }仓库内对应的规则文件位于 detox/android/detox/proguard-rules-app.pro完整的 ProGuard 配置说明可参考 ProGuard 配置指南。Step 2在 CI 脚本中加入 build 与 test 命令假设你的 CI 通过某个 shell 脚本执行任务那么在项目根目录下加入以下两条命令即可detox build --configuration ios.sim.release detox test --configuration ios.sim.release原文档特别用 tip 提示Make sure to shut down the simulator when your tests are over确保测试结束后关闭模拟器。落实到命令层面就是在detox test时追加--cleanup参数detox test --configuration ios.sim.release --cleanup--cleanup与--headlessCI 上最常用的两个参数在 CLI 源码 detox/local-cli/testCommand/builder.js 中可以看到这两个参数的正式定义-u, --cleanupShutdown simulator when test is over, useful for CI scripts, to make sure detox exits cleanly with no residue测试结束后关闭模拟器便于 CI 脚本干净退出、不留残留进程-H, --headlessLaunch device in headless mode. Useful when running on CI以无界面模式启动设备适合 CI。从实现上看detox test本质上是一个参数转环境变量再拉起测试运行器的转发器详见 docs/cli/test.md。在 detox/local-cli/testCommand/TestRunnerCommand.js 的_buildEnvOverride方法中CLI 参数会被翻译为环境变量传递给测试子进程DETOX_CLEANUP: cliConfig.cleanup, // TestRunnerCommand.js#L133 DETOX_HEADLESS: cliConfig.headless, // TestRunnerCommand.js#L143也就是说detox test -u最终等价于在DETOX_CLEANUP1的环境下运行测试运行器如 Jest设备生命周期管理逻辑会在测试结束后据此关闭模拟器/模拟器进程-H同理将DETOX_HEADLESS1传给设备启动逻辑在无显示器的 CI 机器上以-no-window方式启动 Android 模拟器。除了这两个参数docs/cli/test.md 还列出了一些 CI 场景常用的detox test选项同样可在 builder.js 中找到定义参数说明CI 场景下的典型用途-c, --configuration选择配置例如ios.sim.release若不传且配置只有一项Detox 会自动使用它-u, --cleanup测试结束后关闭模拟器保证 CI 干净退出-H, --headless无界面启动设备适合无 GUI 的 CI 机器-R, --retries N对单个失败的测试文件重新拉起测试运行器直到通过或达到 N 次上限可显著降低 CI 上的偶发失败-l, --loglevel日志级别fatal/error/warn/info/verbose/debug/traceCI 排障时常用-l verbose--record-logs,--take-screenshots,--record-videos将日志、截图、录屏写入 artifacts 目录便于 CI 失败时取证-r, --reuse复用已安装的 App不删除重装加快重复运行速度--gpu modeAndroid 专属以指定 GPU 模式启动模拟器如swiftshader_indirect软件渲染适合无 GPU 的 CI--jest-report-specsJest 场景实时输出每个 spec 的日志另外detox test会将未知参数原样转发给底层测试运行器因此你可以在同一行命令里混合使用 Detox 参数与 Jest 参数例如detox test -c ios.debug --showConfig会被翻译为DETOX_CONFIGURATIONios.debug jest --showConfig。当参数名与测试运行器冲突时可用--分隔符显式传递给运行器详见 docs/cli/test.md。Android 端 CI模拟器环境准备与 headless 运行原文档直言Setting up a CI environment capable of running Android tests isnt as trivial搭建能跑 Android 测试的 CI 环境并不轻松。难点主要在于KVM 虚拟化支持Android 模拟器依赖硬件虚拟化KVM才能获得可接受的性能。因此 CI 提供方自带的共享 runner 通常无法直接运行模拟器你需要自建带 KVM 支持的 runner例如选择提供嵌套虚拟化的云主机无界面运行CI 机器通常没有显示器模拟器必须以 headless-no-window模式启动环境的确定性与稳定性Google API 镜像自带的 Google Play 服务、gboard 键盘等组件会占用大量 CPU、诱发测试不稳定因此官方强烈建议使用AOSP 镜像Android Open Source Project而非 Google APIs 镜像来跑自动化测试。AOSP 模拟器的完整搭建流程Java 环境、Android SDK、AOSP 镜像安装、AVD 创建、模拟器快速启动快照、Test Butler 集成等记录在 Android 开发与测试环境搭建指南 中其中包括适合无界面 CI 机器的命令行安装方式# 安装不带 Google APIs 的系统镜像AOSP $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager system-images;android-28;default;x86_64 $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses # 创建 AVD $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd -n Pixel_API_28_AOSP -d pixel \ --package system-images;android-28;default;x86_64 # 无界面启动模拟器适合 Linux 无显示器的 CI 机器 $ANDROID_HOME/emulator/emulator -verbose -no-window -no-audio -gpu swiftshader_indirect Pixel_API_28_AOSP 在 Detox 侧headless 既可以通过 CLI 参数-H指定也可以直接在设备配置中声明。仓库示例 detox/test/e2e/detox.config.js 的做法是跟随 CI 环境变量动态切换android.emulator: { type: android.emulator, headless: Boolean(process.env.CI), // 在 CI 环境自动切换为无界面模式 device: { avdName: Pixel_3a_API_36, }, // ... },同理仓库还会在 CI 环境自动调整测试运行器行为例如 detox/test/e2e/detox.config.js 中testRunner: { args: { $0: process.env.CI ? nyc jest : jest, config: e2e/jest.config.js, forceExit: process.env.CI ? true : undefined, // CI 上强制退出避免挂起 _: [e2e/], }, detached: !!process.env.CI, retries: process.env.CI ? 1 : undefined, // CI 上失败自动重试 1 次 // ... },这种用process.env.CI做条件判断的模式是让同一份 Detox 配置同时服务本地与 CI 的推荐做法。附录三大 CI 平台完整配置示例以下三套配置均直接继承自原文档供你在对应平台上落地时参考。注意其中 Travis 示例属于文档标注为 outdated 的部分基于 Xcode 8.3 时代请以你实际使用的 CI 平台与工具链版本为准。Travis CITravis 示例是模拟器 applesimutils Node的最简组合在install阶段安装 Detox 在 iOS 模拟器上工作所需的applesimutils工具与 Node 环境在script阶段依次执行构建与测试带--cleanuplanguage: objective-c osx_image: xcode8.3 branches: only: - master env: global: - NODE_VERSIONstable install: - brew tap wix/brew - brew install applesimutils - curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash - export NVM_DIR$HOME/.nvm [ -s $NVM_DIR/nvm.sh ] . $NVM_DIR/nvm.sh - nvm install $NODE_VERSION - nvm use $NODE_VERSION - nvm alias default $NODE_VERSION - npm install react-native-cli --global - npm install detox-cli --global script: - detox build --configuration ios.sim.release - detox test --configuration ios.sim.release --cleanupBitriseBitrise 是自动化 React Native 应用时常用的 CI 服务。做法是新建一个名为tests的 workflow拆分为两个子 workflow_tests_setup拉取代码、安装 npm 依赖与_detox_tests全局安装detox-cli与react-native-cli、安装applesimutils、构建 Release App、运行 E2E 测试--- format_version: 1.1.0 default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git trigger_map: - push_branch: * workflow: tests workflows: _tests_setup: steps: - activate-ssh-key: {} - git-clone: inputs: - clone_depth: title: Git Clone Repo - script: inputs: - content: |- #!/bin/bash npm cache verify npm install title: Install NPM Packages before_run: after_run: _detox_tests: before_run: [] after_run: [] steps: - npm: inputs: - command: install -g detox-cli title: Install Detox CLI - npm: inputs: - command: install -g react-native-cli title: Install React Native CLI - script: inputs: - content: |- #!/bin/bash brew tap wix/brew brew install applesimutils title: Install Detox Utils - script: inputs: - content: |- #!/bin/bash detox build --configuration ios.sim.release title: Detox - Build Release App - script: inputs: - content: |- #!/bin/bash detox test --configuration ios.sim.release --cleanup title: Detox - Run E2E Tests tests: before_run: - _tests_setup - _detox_tests after_run: []GitLab CIAndroid OnlyGitLab CI 的官方共享 runner 通常缺少 KVM 支持而无法运行 Android 模拟器因此需要自建带 KVM 的 runner云厂商通常通过提供嵌套虚拟化能力的实例类型来支持。下面这份 job 定义做了三件关键的事准备模拟器通过sdkmanager安装system-images;android-27;default;x86_64注意是default即 AOSP 镜像而非google_apis与emulator再用avdmanager创建名为Nexus6P的 AVD修复系统配置调大 inotify 文件监视上限fs.inotify.max_user_watches避免文件监听溢出初始化/root/.android目录以 headless 模式运行npx detox test -c android.emu.release.ci --headless。detox_e2e: stage: test image: reactnativecommunity/react-native-android variables: before_script: - npm install envinfo detox-cli --global envinfo # Increase file watcher limit, see more here: https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers#the-technical-details - echo fs.inotify.max_user_watches524288 | tee -a /etc/sysctl.conf sysctl -p - mkdir -p /root/.android touch /root/.android/repositories.cfg # The Dockerimage provides two paths for sdkmanager and avdmanager, which the defaults are from $ANDROID_HOME/cmdline-tools # That is not compatible with the one that Detox is using ($ANDROID_HOME/tools/bin) - echo yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --channel0 --verbose system-images;android-27;default;x86_64 emulator # Nexus 6P, API 27, XXXHDPI - echo no | $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager --verbose create avd --force --name Nexus6P --package system-images;android-27;default;x86_64 --sdcard 200M --device 11 - adb start-server script: - npx detox build -c android.emu.release.ci - npx detox test -c android.emu.release.ci --headless注意其中使用了配置名android.emu.release.ci这意味着你需要在.detoxrc.js中预先定义好这个配置包括指向 AOSP 模拟器 AVD 的设备定义与 release 形态的 app 定义Detox 才能据此完成构建与测试。仓库自身的 CI 实践参考当前仓库的 CI 脚本同样是这套方法论的落地样板可以作为你设计自身 CI 流水线的参考scripts/ci.ios.sh 展示了 iOS 侧在 CI 上的完整执行序列先用xcrun simctl list预热模拟器解决重置构建环境后模拟器不可见的问题再执行yarn build:ios与yarn e2e:iosdetox/test/e2e/detox.config.js 集中体现了本地/CI 双模式的配置技巧headless: Boolean(process.env.CI)、retries: process.env.CI ? 1 : undefined、forceExit: process.env.CI ? true : undefined等同时提供 scripts/ci.android.sh、scripts/ci.sh 等脚本涵盖 iOS/Android 双端的 CI 执行与覆盖率收集。小结把 Detox 端到端测试接入 CI 的完整套路可以浓缩为四步准备 Release 配置——在.detoxrc.js中为 iOS/Android 分别定义 release 形态的 app 配置含正确的构建命令、产物路径Android 还需处理 ProGuard 豁免编写 CI 脚本——按detox build --configuration release配置→detox test --configuration release配置 --cleanup的顺序执行处理设备生命周期——用--cleanup保证测试结束即关闭模拟器、用--headless或配置中的headless: Boolean(process.env.CI)适配无界面机器用--retries降低偶发失败Android 单独准备环境——自建带 KVM 的 runner安装 AOSP 镜像并创建 AVD必要时用--gpu swiftshader_indirect等参数适配无 GPU 环境。更完整的 CLI 参数与配置说明可继续阅读 detox test 命令文档、配置总览 与 Android 环境搭建指南。【免费下载链接】DetoxGray box end-to-end testing and automation framework for mobile apps项目地址: https://gitcode.com/gh_mirrors/de/Detox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考