ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Detox 20 发布解读(代号 Ashán):Genymotion SaaS、可配置日志、测试运行器集成与升级迁移指南

Detox 20 发布解读(代号 Ashán):Genymotion SaaS、可配置日志、测试运行器集成与升级迁移指南 Detox 20 发布解读代号 AshánGenymotion SaaS、可配置日志、测试运行器集成与升级迁移指南【免费下载链接】DetoxGray box end-to-end testing and automation framework for mobile apps项目地址: https://gitcode.com/gh_mirrors/de/DetoxDetox 是一个面向移动应用的 Gray box 端到端测试与自动化框架。本文围绕Detox 20 大版本发布展开系统梳理该版本带来的四大核心能力——官方支持 Genymotion SaaS 云端设备、重构测试运行器Test Runner集成契约、可配置的日志子系统、以及 iOS 无头模式、Android 端口反转、只读模拟器、锁文件重置等一批实用性优化并给出从旧版本升级的完整迁移清单。读完本文你将能够在 Detox 配置中接入云端 Android 设备以扩展测试规模、按需定制终端日志与时间线Timeline追踪、掌握新版testRunner配置的完整语义并平稳完成从 Detox 19 到 20 的升级。Detox 20 概览Detox 20 是继 19 之后的一次大版本迭代其改动贯穿「设备、运行器、日志、配置」四条主线官方发布公告中列举的能力包括正式支持 Genymotion SaaS云端 Android 虚拟设备改进与测试运行器Test Runner的集成方式引入可配置的日志子系统Configurable Logger支持通过配置与 CLI 开启 iOS 无头headless模式支持通过 Android 应用配置进行 TCP 端口反转reverse ports为后续 minor 版本预留更多性能优化空间。其中Genymotion SaaS 支持经过了约两年的内部验证早在两年前Wix 就通过 pull request 加入了针对 Genymotion SaaS 的基础支持并进入内测阶段。在此之前Wix 的移动基础设施工程师需要在 CI 构建机上自行维护 Android 虚拟设备切换到云端设备后这部分人力被释放出来投入更高价值的任务对于测试数量庞大的团队当并行设备数从 2 台扩展到 6 台后CI 流水线的耗时几乎缩短了一半。注上述 6 台并非硬性上限而是该团队在设备扩容到 6 台后边际收益急剧下降的拐点——因为除了测试本身安装 NPM 依赖与构建项目同样耗时单纯堆设备并不能无限线性提速。由于当时 PR 中仍存在一些全局生命周期管理方面的小问题Wix 没有急于将该能力对外发布而是选择在生产环境积累更多经验。随后的使用过程相当平稳仅在少数高级场景中出现过零星小问题见 issue #3573。与此同时对 Internals API 的生命周期重构比预期耗时更长这也是 Detox 20 选择在此时发布的原因之一。接入 Genymotion SaaS把 Android 测试搬到云端当端到端测试数量增长后单次测试会话时长很容易超过一两个小时。常规做法是先用测试运行器并行化例如 Jest 传入--maxWorkers N但受限于构建代理能力——一台构建机同时跑几个虚拟设备尚可跑十几个就会变得缓慢且不稳定。因此如果你正面临扩容瓶颈或本地模拟器管理成本过高迁移到 SaaS 平台按需启停设备是更合适的选择。Detox 20 将 Genymotion SaaS 作为一等公民集成详细指南见 使用 Genymotion SaaS。前置条件接入前需要完成两件事在 Genymotion SaaS 注册账号获得可在其 CLI 工具gmsaas中使用的凭据。新注册账号自带2台并发设备与免费60分钟额度安装并配置gmsaasCLI确保执行以下命令能正确回显邮箱gmsaas auth whoami # your_emailexample.com如果出现错误请回头复查 Genymotion 的官方教程与 Known Issues 章节。配置recipe 与设备定义在云端运行测试前需要先定义设备属性OS 版本、屏幕尺寸等这组设备规格在 Genymotion SaaS 中被称为recipe配方。平台提供预置 recipe 列表也支持自定义 recipe。在 recipe 列表展开详情即可看到对应的UUID将其复制到 Detox 配置中module.exports { devices: { simulator: { /* ... */ }, emulator: { /* ... */ }, genycloud: { type: android.genycloud, device: { recipeUUID: paste your chosen recipe UUID }, }, }, apps: { ios.debug: { /* ... */ }, ios.release: { /* ... */ }, android.debug: { /* ... */ }, android.release: { /* ... */ }, }, configurations: { ios.debug: { /* ... */ }, ios.release: { /* ... */ }, android.debug: { /* ... */ }, android.genycloud.release: { device: genycloud, app: android.release, }, }, };recipe 的 UUID 保证唯一且不会随名称变化但如果你更习惯用名称引用也可以改用recipeName属性genycloud: { type: android.genycloud, device: { recipeName: paste the recipe name }, },设备类型的完整取值与说明可参考 设备配置文档type支持ios.simulator、android.emulator、android.attached、android.genycloud等字符串字面量其中android.genycloud的device查询对象在recipeUUID与recipeName二者中取其一。在云端跑 Debug 构建进阶上面示例假设你在 CI 上运行的是 release 配置。若确需在云端运行 debug 构建需要打通本地React Native packager 运行在 8081 端口与云端设备之间的隧道修改MainApplication.java或主 Activity 类强制覆盖debug_http_hostpackage com.example; import android.app.Application; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; -37,6 40,9 public class MainApplication extends Application implements ReactApplication { public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); SharedPreferences preferences PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); preferences.edit().putString(debug_http_host, localhost:8081).apply(); } }在应用配置的reversePorts中加入 8081使本地与远程设备间建立端口隧道该配置项的完整说明见后文android.debug: { type: android.apk, binaryPath: android/app/build/outputs/apk/fromBin/debug/app-fromBin-debug.apk, build: cd android ./gradlew assembleFromBinDebug assembleFromBinDebugAndroidTest -DtestBuildTypedebug cd .., reversePorts: [8081], },清理构建中间产物并重新构建cd android ./gradlew clean # Windows 下去掉 ./ cd .. detox build -c android.emu.debug对于结构简单的应用这些调整通常足以在云端跑通 debug 构建。运行与验证创建好android.genycloud.release配置后即可运行detox test -c android.genycloud.release不久你会看到类似输出其中附带的浏览器链接可以实时观察云端设备画面Allocating Genymotion-Cloud instance Detox.62dfc57b-3201-c861-29bb-8f31f60a8d39.w1 for testing. To access it via a browser, go to: https://cloud.geny.io/instance/8fc62d21-3de0-4ed8-bf18-e69b90246dc5随后建议用 2 个 worker 验证并发场景排查不同测试文件争抢同一资源例如一个测试删除账号而另一个正在使用导致的互斥问题detox test -c android.genycloud.release --maxWorkers 2 # DETOX_CONFIGURATIONandroid.genycloud.release jest --config e2e/jest.config.js --maxWorkers 2注意免费 Genymotion SaaS 账号并发设备上限为2台需要更多设备或时长需联系 Genymotion 团队购买。云端设备的使用注意事项强制终止的泄漏警告。如果通过CtrlC等强制方式中断测试请留意输出的泄漏警告detox[22314] i WARNING! Detected a Genymotion SaaS instance leakage, for the following instances: detox[22314] i Instance Detox.1e0ee8a4-6949-90c7-6680-5c3a9010d1e5.w1 (8fc62d21-3de0-4ed8-bf18-e69b90246dc5) Kill it by visiting https://cloud.geny.io/instance/8fc62d21-3de0-4ed8-bf18-e69b90246dc5, or by running: gmsaas instances stop 8fc62d21-3de0-4ed8-bf18-e69b90246dc5设备无人值守会持续计费务必按提示停止实例gmsaas instances stop 8fc62d21-3de0-4ed8-bf18-e69b90246dc5可在 Genymotion SaaS 管理后台的 Administration Settings 面板设置maximum run duration最大运行时长兜底防止忘记关机造成成本损失。此外CtrlC中断有时也能用来故意保留设备在测试场景中途手动与之交互。shutdownDevice无法被关闭。尽管 Detox CLI 提供了-u, --cleanup参数、行为配置中也有shutdownDevice属性见 behavior 配置但在 Genymotion SaaS 设备上两者都无法真正关闭——测试会话结束时 Detox总是会关闭云端设备除非进程被强制终止。这既能避免忘记关机也意味着无法保留一个随时可用的设备池来服务更繁忙的 CI 流水线属于当前版本已知的取舍。与测试运行器Test Runner的集成重构Detox 本质不是一个测试运行器而是运行在某个测试运行器之上。Detox 20 花费数月时间把 Detox 与测试运行器之间的契约contract正式化集成方式从「实现耦合」变为「配置驱动」——Detox 源码中除少数默认值外如testRunner.args.$0与testRunner.inspectBrk钩子以及detox testCLI 对 Jest 布尔参数如-i, --runInBand、--bail的识别与自动修正几乎没有针对 Jest 的硬编码逻辑。这套重构也同时为第三方测试运行器集成Internals API打下基础。为何放弃 Mocha押注 JestMocha 是 Detox 最早支持的测试运行器但随着端到端测试数量增长Mocha 无法跟上扩展需求。当 Mocha 8 终于具备并行测试能力时Detox 已经把赌注压在了 Jest 上。团队一度试图同时兼容 Jest 与 Mocha但代价越来越大Jest 的首次集成过于简陋两年多的生产使用中不断暴露问题迫使团队将两者之间的「胶水代码」推倒重写了两次。最终在 Detox 20 中正式停止支持 Mocha把精力集中在 Jest 与新引入的、与运行器无关的 testRunner 配置 与 Internals API 上。如果社区有足够需求由开源社区为 Detox 与 Mocha 构建新的第三方集成。testRunner配置详解testRunner配置节负责拼装detox test将要拉起的测试运行器命令其通用形态为detox test # $0 --key1 value1 … ---keyN valueN ...positionalArguments例如{ testRunner: { args: { $0: nyc jest, bail: true, config: e2e/jest.config.js, _: [e2e/sanity-tests] } } }等价于执行nyc jest --bail --config e2e/jest.config.js e2e/sanity-tests各属性语义如下testRunner.args.$0默认jest测试运行器命令的起始部分通常是可执行文件名按PATH环境变量解析。虽然不推荐也支持复合命令如node -r ./preload.js node_modules/.bin/my-runner。testRunner.args[…]以键值对形式定义任意参数。false布尔值会自动生成--no-前缀的键{ args: { $0: jest, color: false, bail: true, testTimeout: 60000, config: e2e/jest.ci.config.js } }生成命令为jest --no-color --bail --testTimeout 60000 --config e2e/jest.ci.config.jstestRunner.args._默认[]传递给运行器的默认位置参数。不带额外位置参数运行时_内容会被追加带自定义位置参数时_内容被替换detox test -c ios.sim.debug # jest … e2e/sanity-tests detox test e2e/regression-tests # jest … e2e/regression-tests注意使用detox test的重试机制时失败测试文件路径会覆盖_并在后续重跑中使用。testRunner.retries默认0让detox test反复重跑失败测试文件直到通过或达到重试次数上限。也可用 CLI 参数-R, --retries见 detox test CLI 文档覆盖。testRunner.bail默认false为true时若收到一次「永久性测试套件失败」permanent test suite failure详见 Internals API 的结果上报则取消后续重试仅在retries大于 0 时生效。testRunner.noRetryArgs默认[shard]重试失败测试时需要从命令中移除的参数名数组。例如默认配置下重试时会移除shard参数# 首次带分片运行 jest --shard1/3 e2e/tests # 重试时去掉分片只跑失败测试 jest path/to/failed/test.js可按需扩展该数组{ testRunner: { noRetryArgs: [shard, maxWorkers, customArg] } }testRunner.detached默认false为true时detox test以分离模式detached拉起测试运行器。适用于 CI 环境——需要拦截 SIGINT/SIGTERM 以优雅关闭运行器与设备时Detox 不再向子进程转发 kill 信号而是向所有 worker 发送紧急关闭请求并等待其完成。testRunner.forwardEnv默认false启用后detox test会把命令行参数以环境变量形式传给测试运行器detox test -c ios.sim.debug --record-logs all DETOX_CONFIGURATIONios.sim.debug DETOX_RECORD_LOGSall jest …即使关闭该选项Detox 仍会打印去掉 CLI 包装后可直接调用的测试运行器命令方便你在 IDE 中复制粘贴调试。testRunner.inspectBrk函数默认是 Jest 专用回调——设置$0、--runInBand并清理-w, --maxWorkers主要在开发第三方运行器集成时使用。当detox test带--inspect-brk调用时触发用于准备 Node.js inspector 调试见 调试指南/* type {Detox.DetoxConfig} */ module.exports { testRunner: { /** param {Detox.DetoxTestRunnerConfig} config */ inspectBrk: (config) { config.args.$0 os.platform() win32 ? node --inspect-brk ./node_modules/jest/bin/jest.js : node --inspect-brk ./node_modules/.bin/jest; config.args.runInBand true; delete config.args.w; delete config.args.workers; }, }, };testRunner.jest这是 Jest 集成代码而非 Detox 核心使用的附加配置节。若你实现自定义运行器集成同样可以为自己定义专属配置节例如testRunner.mocha。其子属性包括jest.setupTimeout默认120000即 2 分钟Detox 在环境初始化阶段environment setup需要启动设备并安装应用超过该时长则整个测试套件判为失败错误信息形如Exceeded timeout of 120000ms while setting up Detox environmentjest.teardownTimeout默认30000即 30 秒环境拆除environment teardown超时阈值jest.reportSpecs默认undefined即自动默认 Jest 会在会话结束时才打印测试名与状态对秒级单元测试尚可但对分钟级的端到端测试体验很差。启用后Detox 会在每个测试开始/结束时实时打印[OK]状态行默认在单 worker 会话中自动开启多 worker 并发时自动关闭以避免日志混乱可用true/false显式控制jest.reportWorkerAssign默认true初始化阶段设备被分配给某个测试套件时打印形如starter.test.js is assigned to 4EC84833-... (iPhone 12 Pro Max)的消息jest.retryAfterCircusRetries默认falseJest 提供jest.retryTimes(count)API 可重跑单个失败测试。当 Detox 检测到该 API 被使用时会抑制自身的 CLI 级重试机制detox test --retries N或testRunner.retries避免两个机制叠加导致测试时长成倍增长若确实想同时启用两者将其设为true。与 Jest 的集成detox init生成的 jest.config.js 剖析detox init生成的 Jest 配置有助于理解 Detox 与 Jest 的集成方式见 testRunner 配置文档/** 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, };各属性的作用与定制要点rootDir与testMatch约定测试文件以.test.js结尾并位于e2e目录与 Jest 配置同目录testTimeout: 120000覆盖 Jest 默认的 5 秒超时——端到端测试在 5 秒内几乎不可能完成2 分钟是较稳妥的默认值可按需增减maxWorkers: 1防止按 Jest 默认策略cpusCount - 1过度分配移动设备——例如 6 核笔记本会尝试拉起 11 台设备。可临时用--maxWorkers N覆盖也可按环境动态设置默认值/** type {import(jest/types).Config.InitialOptions} */ module.exports { // … maxWorkers: process.env.CI ? 2 : 1, };globalSetup/globalTeardown是接入 Detox Internals API 的关键。如需追加自己的逻辑应包裹调用// globalSetup 追加逻辑 module.exports async () { await require(detox/runners/jest).globalSetup(); await yourGlobalSetupFunction(); }; // globalTeardown 追加逻辑注意 try/finally module.exports async () { try { await yourGlobalTeardownFunction(); } finally { await require(detox/runners/jest).globalTeardown(); } };reporters数组必须始终包含 Detox 提供的 reporterdetox/runners/jest/reporter——Detox 保留随时在其中注入集成代码的权利缺失它会在未来升级版本时带来风险testEnvironment是整个集成的核心。需要扩展时应继承DetoxCircusEnvironment位于 runners/jest 目录例如testEnvironment.js中的detox/runners/jest/testEnvironment并在setup/handleTestEvent/teardown中调用super对应方法后追加自定义代码verbose: true用于关闭 Jest 的日志批处理log batching确保实时看到日志输出。全局变量、Mocking 与并行执行全局变量除非behavior.init.exposeGlobals设为falseDetox 会把expect、device等原语暴露为全局变量并覆盖 Jest 的全局expect。若仍需要使用 Jest 的expect请显式导入import jestExpect from expect;。Mocking不要使用jest.mock()或类似机制应遵循 Mocking 指南。并行执行Detox 依赖测试运行器并行执行测试。使用 Jest 时最简单的方式是detox test … --maxWorkers 2其他运行器请查阅各自文档。参数透传Detox 不认识的 CLI 参数会原样透传给底层测试运行器Jest 会打印Unrecognized CLI Parameters提示。若 Detox 与运行器参数冲突可用--双横线强制原样转发例如detox test -c ios.sim.debug -- --help会执行jest --help。可配置日志子系统从「一堆文件」到detox.logdetox.trace.json日志子系统的僵化问题自 2019 年夏季 logger 重写 起就一直存在由于时间与技术债限制初版更像一个 proof-of-concept。其典型症状在使用 timeline 与日志产物尤其是并行测试时尤为明显令人困惑的文件数组detox_pid_7505.log、detox_pid_7505.log.json、detox_pid_7506.log结构过浅的detox.trace.json只包含测试套件、测试函数和少量用户自定义分段。Detox 20 将所有这些日志收敛为两个文件detox.log—— 人类可读的纯文本日志detox.trace.json—— 机器可读的原始时间线文件可用chrome://trace、Perfetto 等工具加载。用 Logger API 为时间线添加自定义事件借助新的 Logger API你可以把自定义耗时事件写入时间线。完整的事件语义包含log.*([event,] ...msg)记录即时消息共六个级别log.fatal/error/warn/info/debug/tracelog.*.begin([event,] msg)/log.*.end([event, msg])标记一段耗时事件的开始与结束在时间线上显示为连续彩色分段支持嵌套与叠加务必成对结束否则事件会被标记为 unfinishedlog.*.complete([event,] msg, functionOrPromise)begin与end的便捷封装自动为结束事件附加{ success: true }或{ success: false, error }元数据是官方推荐的追踪方式。发布公告给出的示例await detox.log.trace.complete(Login, async () { await element(by.id(email)).typeText(johnexample.com); await element(by.id(password)).typeText(123456); detox.log.info(Trying to log in...); await element(by.id(submit)).tap(); });事件元数据中还有几个影响时间线渲染的特殊字段id字符串/数字用于区分并发重叠事件防止嵌套事件超出父事件导致时间线错乱带id开始事件时 logger 会分配独立tid即新「车道」、cat事件分类字符串或数组便于过滤如{ cat: login,login-email }等价于{ cat: [login, login-email] }、cname自定义事件颜色、以及任意自定义属性args、data、error、stack、origin等名称拥有默认格式化规则。pid、tid、ts、ph为保留字段不可自行记录。通过logger配置定制终端输出detox.log包含终端可见的全部消息含所有级别而终端本身的输出样式则完全由 logger 配置 控制logger.level枚举默认info按严重程度降序为fatal、error、warn、info、debug、trace。日常用info希望输出尽量安静用error/warn排查内部运行状态用debug定位具体问题用trace。注意日志级别只过滤终端输出不影响生成的日志文件及其内容。日志的详细程度还会受session.debugSynchronization默认开启影响它会输出形如The app is busy with the following tasks:的同步阻塞原因日志设为0可关闭、调大如60000可降低记录频率见 session 配置 与 How Detox Works。logger.overrideConsole布尔默认true开启后劫持所有 console 方法console.log、console.warn等使其输出被格式化为 Detox 日志并保存。logger.optionsBunyanDebugStreamOptions默认随logger.level变化Detox 使用 bunyan-debug-stream 打印日志因此直接暴露其全部选项包括colors、forceColor、showDate、showPrefixes、prefixers、stringifiers、indent、showLoggerName、showPid、showLevel、showMetadata等。发布公告中的示例——去掉日志消息周围的元数据/** type {Detox.DetoxConfig} */ module.exports { // ... logger: { options: { showDate: false, showLoggerName: false, showPid: false, prefixers: { ph: null, }, }, }, };logger.options中有一个重要陷阱所有自定义函数不得使用闭包。因为这些函数在测试运行器每次派生新的子 worker 进程时都会被eval()重新求值。正确写法是把函数体直接内联const dontDoThis date date.toISOString(); module.exports { logger: { level: debug, options: { // showDate: (date) dontDoThis(date), // 错误使用了闭包 showDate: (date) date.toISOString(), /* 正确直接内联 */ }, }, // ... };次要特性headless、reversePorts、只读模拟器与锁文件重置iOS 无头Headless模式长期以来除非手动打开 Simulator.app否则无法在本地模拟器上看到测试运行画面。Detox 20 统一了 iOS 与 Android 的headless属性两个平台默认都会可见地启动设备除非显式配置为无头模式/* type {Detox.DetoxConfig} */ module.exports { devices: { iphone: { type: ios.simulator, headless: process.env.CI ? true : undefined, device: { type: iPhone 14 }, /* ... */ } }, };或通过 CLI 直接指定detox test -c ios.sim.release --headless依据 设备配置文档headless为可选布尔值默认false设为true时Android 模拟器以-no-window启动iOS 则不打开 Simulator 应用。Android 应用端口反转reversePorts应用可能访问localhost:*地址例如 mock 服务器但在 Android 上这并不简单——Android 模拟器是独立的虚拟设备拥有自己的 loopback 网络接口必须通过adb reverse设置反向端口转发。本地服务器React Native bundler 的 8081 端口、Storybook 的 9009 端口等是 debug 模式应用的常见依赖因此 Detox 20 为 Android 应用配置新增了可选的reversePorts属性/** type {Detox.DetoxConfig} */ module.exports { // ... apps: { android.debug: { type: android.apk, binaryPath: ..., reversePorts: [8081, 3000], }, }, };从源码实现看reversePorts属于「配置优先于代码」的便利 API在 RuntimeDevice.js 的installApp()中应用安装完成后会遍历currentApp.reversePorts并逐个调用reverseTcpPort(port)——即等价于在每次安装应用后自动执行device.reverseTcpPort(portNumber)。同时在 composeAppsConfig.js 中会校验该属性仅对android.apk类型生效非 Android 应用配置携带reversePorts会被拒绝相关断言见 composeAppsConfig.test.js运行期行为测试见 RuntimeDevice.test.js。对应参数说明同样收录于 应用配置文档。Android 模拟器默认只读模式-read-only标志自 Android 模拟器 28.0.16 起可用它允许同一 AVD 并发运行多个实例这正是 Detox 实现 Android 并行测试执行的基础。此前 Detox 过于谨慎只在多 worker 并发时启用只读模式从而制造了一个恼人的体验问题先用单 worker 顺序跑测试得到普通非只读AVD 实例之后切到多 worker 时模拟器会报错拒绝混用普通与只读实例。虽然修复方法简单关闭正在运行的 AVD 再重试但过度谨慎带来的问题远多于解决。因此从 Detox 20 起Android 模拟器默认总是以-read-only模式启动除非在设备配置中显式设置readonly: false。依据 设备配置文档readonly仅对android.emulator生效默认false设为true时强制即使单个模拟器也用-read-only启动且多 worker 场景下该设置无效——模拟器始终以只读方式启动。detox reset-lock-file多配置并行运行的锁文件救星Detox 使用文件锁机制避免并行测试 worker 抢占同一设备。detox test命令启动时会清空锁文件内容从而引入竞态风险。若想同时运行多个 Detox 配置的测试例如detox test -c iphoneSE2020.release e2e/ui.test.js detox test -c iphone14ProMax.release e2e/ui.test.js应改用detox reset-lock-file与--keepLockFile的组合detox reset-lock-file \ detox test --keepLockFile -c iphoneSE2020.release e2e/ui.test.js \ detox test --keepLockFile -c iphone14ProMax.release e2e/ui.test.js \ wait该工具的使用说明见 detox reset-lock-file 文档锁文件记录设备的忙闲状态确保同一设备不会被多个 Detox 测试会话同时使用。默认情况下detox test启动时也会清理锁文件但只针对已分配给「死进程/不存在进程」的设备而detox reset-lock-file会彻底清空锁文件。官方表示未来计划最小化锁文件的使用让用户无需关心这一底层实现细节该工具是过渡期的便利方案。Deprecations从 Detox 19 升级到 20 的迁移清单Detox 20 执行了大量积压的弃用项升级前务必核对 迁移指南尤其 20.0 一节。完整清单如下JS 运行时要求最低支持 Node.js 版本为14.x最低支持 Jest 版本为27.2.5推荐 28.x 或 29.xMocha 测试运行器不再被支持可用detox init样板与 testRunner 配置 作为迁移参考或等待社区第三方集成废弃旧版 Jest 适配器jest-jasmine与第一代jest-circus适配器废弃device.appLaunchArgs.*方法中的{ permanent: true }选项PR #3360改用device.appLaunchArgs.shared.modify({ ... })。CLI移除-w, --workers与-o, --runner-config参数——Detox 不再关心第三方运行器的参数需要改为直接透传给 Jestdetox test … --config path/to/jest.config、detox test … --maxWorkers 3移除已废弃的--device-launch-argsPR #3665改用--device-boot-args。配置停用 kebab-case 属性test-runner、runner-configPR #3371停用skipLegacyWorkersInjections属性PR #3286废弃specs与runnerConfig顶层属性改变testRunner属性的语义从字符串改为对象见 testRunner 配置停止支持 all-in-one 配置PR #3386。Android/iOSAndroid移除已废弃的原生 IdlePolicyConfigPR #3332iOS停用ios.none设备类型改用新的 调试原生代码 方式PR #3361。迁移要点速览all-in-one 配置拆分。若遇到DetoxConfigError: Configuration legacy uses a deprecated all-in-one schema需要把配置拆分为apps、devices、configurations三节完整对照示例见 迁移指南。testRunner节。三个顶层字符串属性被统一为对象形式- testRunner: jest, - runnerConfig: e2e/jest.config.js, - specs: e2e, - skipLegacyWorkersInjection: true, testRunner: { $0: jest, args: { config: e2e/jest.config.js, _: [e2e] }, },若此前未配置runnerConfig需显式补上config: e2e/config.json这是 Detox 19 及更早版本的隐式默认值。setupTimeout、reportSpecs、reportWorkerAssign等初始化行为也统一收归testRunner.jest节替代原先生成e2e/environment.js样板代码的做法。Jest 配置。新配置需要引入detox/runners/jest/reporter、globalSetup、globalTeardown与testEnvironment四个集成点并推荐以rootDirtestMatch取代testRegex同时移除streamlineReporter详见 迁移指南 中的逐行说明。自定义环境类改为从detox/runners/jest导入原先为detox/runners/jest-circusSpecReporter、WorkerAssignReporter不再导出this.initTimeout更名为this.setupTimeout。timeline 产物。若曾使用--record-timeline all或配置中的artifacts.plugins.timeline请从配置与脚本中移除——timeline 产物已合并进日志产物只要不关闭 logs 就会得到detox.trace.json。环境变量。依赖process.env.DETOX_CONFIGURATION等变量的代码可临时开启testRunner.forwardEnv缓解但更推荐的方案是改用 Internals API例如const { resolveConfig } require(detox/internals); module.exports async () { const { device } await resolveConfig(); return { maxWorkers: process.env.CI ? (device.type ios.simulator ? 3 : 2) : 1, globalSetup: ..., globalTeardown: ..., // ... and so on ... }; };结语围绕「规模化」的下一步在 Wix 内部过去一年半里 Detox 团队为超过 50 个项目建立了集中化配置体系并排查了上百个问题。Detox 20 之后的改进方向可以归结为一个词——规模化scaling它几乎涵盖了团队近期遇到的所有挑战用户数增长→ 改进上手与排障体验项目数增长→ 将分散的配置收敛为灵活的组织级预设测试数增长→ 优化代码库并偏向云端与远程执行。评估每个新功能时团队只问一个问题它能否节省大家的时间让我们把精力放在更重要的事情上基于此后续工作将围绕上述三个方向持续展开。对使用者而言Detox 20 的 Genymotion SaaS 支持、可配置日志与运行器无关的集成契约正是为「更大规模的端到端测试」铺路的第一步。文中涉及的关键配置与源码入口testRunner 配置、logger 配置、Logger API、设备配置、应用配置、Genymotion SaaS 指南、reset-lock-file 文档、迁移指南、Internals API以及源码实现 RuntimeDevice.js 与配置校验 composeAppsConfig.js。【免费下载链接】DetoxGray box end-to-end testing and automation framework for mobile apps项目地址: https://gitcode.com/gh_mirrors/de/Detox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表