测试移动开发质量保障开发工具【免费下载链接】DetoxGray box end-to-end testing and automation framework for mobile apps项目地址https://gitcode.com/gh_mirrors/de/Detox点击查看免费下载Detox 作为移动端灰度gray-box端到端测试框架原生支持 Android 设备与 iOS 模拟器。但当你的应用目标是 Web、Windows 等第三方平台时就需要借助第三方驱动程序Third-Party Drivers机制将同一套测试能力扩展到新平台。本文以 docs/articles/third-party-drivers.md 为骨架结合仓库中 examples/demo-plugin/driver.js 的完整示例与detox/src下的工厂/基类源码系统讲解第三方驱动程序的安装使用、五类核心契约类的实现要求与运行时装配原理帮助读者既会用第三方驱动也能从零写一个合规的驱动。什么是第三方驱动程序Detox 内置了对两大主流平台的支持其实现方式是在 Detox 配置中选择对应的驱动类型driver type。例如下面的配置片段启用了ios.simulator驱动{ ios.sim: { type: ios.simulator, device: ..., binaryPath: bin/YourApp.app } }其中type字段决定了 Detox 在本次运行中实例化哪一套平台实现。从源码结构看内置驱动的运行时实现集中在 detox/src/devices/runtime/drivers/index.js它导出了四类运行时驱动AndroidEmulatorRuntimeDriver来自android/emulator/EmulatorDriver.jsAttachedAndroidRuntimeDriver来自android/attached/AttachedAndroidDriver.jsGenycloudRuntimeDriver来自android/genycloud/GenyCloudDriver.jsIosSimulatorRuntimeDriver来自ios/SimulatorDriver.js而设备分配层的驱动则位于 detox/src/devices/allocation/driversAndroid 的AndroidAllocDriver.js、模拟器与 Genymotion Cloud 的分配驱动以及 iOS 的SimulatorAllocDriver.js。虽然 Detox 开箱即用地支持 Android 设备与 iOS 模拟器但运行 Web如 react-native-web或 Windows如 react-native-windows等平台的应用同样可以被定向测试。此时你可以切换到第三方驱动程序来在这些平台上运行测试如果现成的驱动不存在也可以按照本文的契约自己编写一个。如何使用第三方驱动程序使用第三方驱动的整体流程非常简单通常三步即可完成。在开始之前请先确认目标平台是否已有现成的第三方驱动参见下文已有的第三方驱动程序一节大多数驱动会自带安装说明。安装驱动包将驱动作为开发依赖安装进项目的package.jsonnpm install --save-dev detox-driver-package新增 Detox 配置在现有配置中加入一个新配置项并将其type设置为驱动的包名 thirdparty.driver.config: { type: detox-driver-package, binaryPath: bin/YourApp.app, }运行 Detox通过--configuration指定新配置的名称执行测试detox test --configuration thirdparty.driver.config在运行时Detox 会依据配置中的type值去加载对应的驱动模块。需要特别注意的是Detox 对第三方驱动模块导出的字段有强制校验——例如分配层工厂在 detox/src/devices/allocation/factories/external.js 中若模块未导出DeviceAllocationDriverClass会直接抛出DetoxRuntimeError运行时工厂 detox/src/devices/runtime/factories/external.js 则要求导出RuntimeDriverClass匹配器工厂 detox/src/matchers/factories/index.js 要求导出ExpectClass。这意味着驱动包必须按固定契约导出命名类否则 Detox 会在启动阶段报出形如The custom driver at ... does not export the RuntimeDriverClass property的错误。驱动程序的内部结构Anatomy of the Drivers理解驱动架构有助于编写第三方驱动。Detox 的整体运行分为宿主机 Node.js 进程中的测试逻辑执行与被测设备中被注入测试应用的原生客户端两大部分可参见 docs/articles/how-detox-works.md 的架构说明Tester 运行于宿主机 Node.js 进程Detox 原生客户端被集成进被测应用两者通过 Detox 中介服务器以 WebSocket 通信。运行在宿主机 Node.js 进程、负责执行测试逻辑的组件包括设备驱动层Device Drivers layer包含一组驱动主要但不完全实现 Detox 测试中暴露的device对象 的平台特定细节。该实现负责管理测试运行的设备——包括设备分配、应用安装、用户交互例如点击 tap的执行等。在源码中这一层对应的抽象基类是 detox/src/devices/runtime/drivers/DeviceDriverBase.js它定义了launchApp、installApp、terminate、takeScreenshot、sendToHome、setOrientation、setLocation等一系列供上层 device API 调用的平台操作占位实现并持有client负责与原生端通信与emitter事件总线两个依赖。匹配器Matchers为测试中的expect、element、waitFor与by全局对象提供能力支撑。本质上它负责把测试逻辑命令如点击与断言翻译并经由网络发送到被测设备由设备原生地执行这些命令。内置实现参见 detox/src/android/AndroidExpect.js 与 detox/src/ios/expectTwo.js第三方驱动则通过导出ExpectClass提供自定义实现。运行在被测设备、被注入测试应用内部的组件原生客户端Native Client驱动客户端通过 WebSocket 与 Detox 服务器通信接收序列化后的匹配器与断言信息并回传测试每一步成功或失败的响应。通常设备客户端会使用平台特有的底层库来实现断言。在 Detox 内部宿主机侧的客户端实现位于 detox/src/client/Client.js 与 detox/src/client/AsyncWebSocket.js。编写新的第三方驱动为了引入一个第三方驱动你需要实现一组核心类每一个类负责 Detox 的一项关注点Allocation设备分配启动/选择测试将要运行的设备的过程。Pre-validation环境预校验对执行环境进行检查例如验证 Android SDK 是否已安装。Artifact handlers registration产物处理器注册注册基于平台的产物生成处理器例如截图处理器Android 与 iOS 平台各不相同。Runtime运行时测试逻辑的实际执行。Matchers匹配器可见元素匹配与可见性断言。要了解这些类的精确契约可以参考仓库中 examples/demo-plugin/driver.js 的模拟实现dummy implementation它演示了全部五个契约类的最小可用写法。驱动的模块导出契约examples/demo-plugin/driver.js末尾的导出语句展示了第三方驱动模块必须导出的全部字段module.exports { ExpectClass: PluginExpect, EnvironmentValidatorClass: PluginEnvironmentValidator, ArtifactPluginsProviderClass: PluginArtifactsProvider, DeviceAllocationDriverClass: PluginDeviceAllocationDriver, RuntimeDriverClass: PluginRuntimeDriver, };对照上文提到的工厂校验逻辑可以得到契约全貌导出字段对应关注点校验工厂源码DeviceAllocationDriverClass设备分配detox/src/devices/allocation/factories/external.js必填缺失即抛错RuntimeDriverClass运行时执行detox/src/devices/runtime/factories/external.js必填缺失即抛错ExpectClass匹配器/断言detox/src/matchers/factories/index.js必填缺失即抛错EnvironmentValidatorClass环境预校验detox/src/devices/validation/factories/index.js可选缺省时回退到Noop空校验器ArtifactPluginsProviderClass产物插件注册detox/src/artifacts/factories/index.js可选缺省时回退到EmptyProvider即不产生任何产物值得留意的是环境校验器与产物提供者是可选的。环境校验工厂在 detox/src/devices/validation/factories/index.js 中只有当模块导出EnvironmentValidatorClass时才实例化自定义校验器否则使用Noop工厂创建一个空校验基类 detox/src/devices/validation/EnvironmentValidatorBase.js产物工厂在 detox/src/artifacts/factories/index.js 中同样做了回退处理ArtifactPluginsProviderClass缺失时采用EmptyProvider。因此一个最小可用的第三方驱动可以只实现分配、运行时与匹配器三个必填类。骨架实现Skeletal Implementation大致上一个第三方驱动的预期骨架实现如下与文档一致的完整版const DeviceDriverBase require(detox/src/devices/runtime/drivers/DeviceDriverBase); class Cookie { constructor(id) { this.id id; // 持有标识关联设备所需的任何信息 } } class MyNewAllocationDriver { constructor(deps) { this.emitter deps.eventEmitter; } async allocate(deviceConfig) { // ... return new Cookie(id); // 在整个进程生命周期内仅创建一次的 cookie } async free(cookie, options) { // ... } } class MyNewEnvValidator { validate() { // ... } } class MyNewArtifactsProvider { declareArtifactPlugins() { // ... } } class MyNewRuntimeDriver extends DeviceDriverBase { constructor(deps, cookie) { // ... } // ... } class MyExpect { // ... } module.exports MyNewDriver;设备分配驱动Allocation Driver分配驱动负责找设备。其构造器接收deps其中eventEmitter可用于在分配/释放生命周期内发射事件。allocate(deviceConfig)在设备分配完成后返回一个Cookie携带标识该设备的必要信息整个进程生命周期只创建一次free(cookie, options)负责释放设备及关联资源。Demo 示例 examples/demo-plugin/driver.js 给出了更贴近实际的写法class PluginDeviceAllocationDriver { constructor(deps) { this.emitter deps.eventEmitter; } async allocate(deviceConfig) { console.log(TODO Allocate an actual device here, deviceConfig.device); return { id: device ID }; } async free(cookie, { shutdown }) { console.log(TODO: Free up device and resources, here); if (shutdown) { await this.emitter.emit(beforeShutdownDevice, { deviceId: id }); await this.emitter.emit(shutdownDevice, { deviceId: id }); } } }注意其中的beforeShutdownDevice与shutdownDevice事件发射——这是 Detox 设备生命周期事件体系的体现分配层事件最终会被上层设备/服务器订阅参考 detox/src/devices/allocation 目录下各类分配驱动对事件的使用。参照内置实现可进一步阅读 detox/src/devices/allocation/drivers/android/AndroidAllocDriver.js 与 detox/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js 了解真实平台驱动是如何做设备发现、启动与端口管理的。运行时驱动Runtime Driver运行时驱动继承自 detox/src/devices/runtime/drivers/DeviceDriverBase.js是测试逻辑的实际执行者。基类已经给出了全部平台操作的默认占位实现launchApp返回NaN、takeScreenshot返回空串等第三方驱动按需覆写即可。Demo 示例覆写了几个关键方法class PluginRuntimeDriver extends DeviceDriverBase { constructor(deps, cookie) { super(deps); this.cookie cookie; this.app new PluginApp(deps); } getExternalId() { return this.cookie.id; } getDeviceName() { return Plugin; // TODO } async launchApp(bundleId, launchArgs, languageAndLocale) { const deviceId this.cookie.id; await this.emitter.emit(beforeLaunchApp, { bundleId, deviceId, launchArgs, }); const pid PID; await this.emitter.emit(launchApp, { bundleId, deviceId, launchArgs, pid, }); return pid; } validateDeviceConfig(deviceConfig) { this.deviceConfig deviceConfig; if (!this.deviceConfig.binaryPath) { throw new Error( binaryPath property is missing, should hold the app binary path:\n JSON.stringify(deviceConfig, null, 2) ); } } async waitUntilReady() { await this.app.connect(); } }这里展示了运行时驱动中值得关注的几个要点构造器签名constructor(deps, cookie)——deps中至少包含client与eventEmittercookie即分配阶段产出的设备标识。工厂在实例化时通过 detox/src/devices/runtime/factories/external.js 传入{ ...deps, ...configs }与deviceCookie。事件发射launchApp等操作会在执行前后发射beforeLaunchApp、launchApp等事件供产物artifacts体系与日志体系订阅——这正是 detox/src/artifacts/factories/index.js 中artifactsManager.subscribeToDeviceEvents(eventEmitter)所消费的事件流。配置校验validateDeviceConfig可用于校验binaryPath等必需配置项并给出可读错误。waitUntilReady基类默认实现是this.client.waitUntilReady()等待与原生端的 WebSocket 连接就绪第三方驱动可覆写为自定义的应用就绪判定逻辑。匹配器Expect Class匹配器为by、element、expect、waitFor提供能力。Demo 中的PluginExpect给出了最小实现by暴露accessibilityLabel、label、id、type、traits、value、text等匹配方法element(matcher)与expect(element)定义了测试中可用的断言原语class PluginExpect { constructor({ invocationManager }) { this._invocationManager invocationManager; this.by { accessibilityLabel: (value) {}, label: (value) {}, id: (value) value, type: (value) {}, traits: (value) {}, value: (value) {}, text: (value) {}, }; this.element this.element.bind(this); this.expect this.expect.bind(this); this.waitFor this.waitFor.bind(this); } expect(element) { return { toBeVisible: () { if (!element) { throw new Error(Expectation failed); } } } } element(matcher) { return matcher welcome; } waitFor(element) { } }工厂层通过 detox/src/matchers/factories/index.js 的createMatchers(deps)直接new出ExpectClass实例deps中会携带invocationManager、runtimeDevice与eventEmitter等依赖。内置实现可对照 detox/src/android/AndroidExpect.js 与 detox/src/ios/expectTwo.js 了解真实驱动如何将匹配器序列化并通过invocationManager下发到原生端。环境校验器Environment Validator与产物提供者Artifacts Provider这两个类是可选的class PluginEnvironmentValidator { async validate() { console.log(TODO: perform some validations); } } class PluginArtifactsProvider { declareArtifactPlugins() { console.log(TODO: Set up artifact generation handlers); return {}; } }环境校验器validate()在测试运行前检查执行环境如 SDK、平台工具链是否就绪。内置示例可参考 detox/src/devices/validation 目录如 iOS 模拟器校验器IosSimulatorEnvValidator、Genymotion Cloud 校验器GenycloudEnvValidator前者通过 detox/src/devices/validation/factories/index.js 中的IosSimulator工厂创建。产物提供者declareArtifactPlugins()返回平台产物插件注册表如截图、日志、视图层级等产物的处理器。内置的 Android/iOS 产物提供者位于 detox/src/artifacts/providersAndroidArtifactPluginsProvider、IosArtifactPluginsProvider等其声明结果会在 detox/src/artifacts/factories/index.js 中通过registerArtifactPlugins注册进ArtifactsManager。客户端应用App ClientDemo 中还演示了一个可选的PluginApp类——当第三方平台需要自定义的应用端连接协议时可以像这样通过deps.sessionConfig与deps.client在connect()中建立会话class PluginApp { constructor(deps) { this.configuration deps.sessionConfig; this.client deps.client; } async connect() { // NOTE: 自定义应用客户端的示例事件处理方式测试套件中并非必需 // // const { Action } require(detox/src/client/actions/actions); // class PongAction extends Action { // constructor(messageId) { // super(ping, { messageId }); // } // // handle() { // } // } // // this.client.setEventCallback(ping, async (json) { // await this.client.sendAction(new PongAction(json.messageId)); // }); } }注释中展示了如何基于 detox/src/client/Client.js 与 detox/src/client/actions 中的Action类通过client.setEventCallback监听服务器推送事件、用client.sendAction发送自定义动作——这是理解 Detox 客户端-服务器协议参见 docs/architecture/client-server.md后扩展自定义平台通信的入口。已有的第三方驱动程序detox-puppeteer一个真实世界中的第三方驱动实现将 Detox 的测试能力桥接到 Puppeteer 所控制的 Web 环境可作为编写新驱动时的参考实现。小结第三方驱动程序机制将 Detox 的设备管理 匹配器 原生客户端架构抽象为一组可插拔的契约类使用侧只需三步安装驱动包 → 配置type为驱动包名 → 以该配置运行测试开发侧则需要按固定契约导出DeviceAllocationDriverClass、RuntimeDriverClass、ExpectClass三个必填类并可选择性地提供EnvironmentValidatorClass与ArtifactPluginsProviderClass。仓库中 examples/demo-plugin/driver.js 的完整示例与 detox/src/devices/runtime/drivers/DeviceDriverBase.js 的基类定义是快速上手编写自有平台驱动的最佳起点。赞分享测试移动开发质量保障开发工具【免费下载链接】DetoxGray box end-to-end testing and automation framework for mobile apps项目地址https://gitcode.com/gh_mirrors/de/Detox点击查看免费下载相关推荐FirebaseUI Web测试驱动开发单元测试与端到端测试完整指南FirebaseUI Web测试驱动开发单元测试与端到端测试完整指南 FirebaseUI Web是一个开源的JavaScript库为Firebase SD前端UI组件认证鉴权专业级VDB插件实战指南从零掌握Unreal体积渲染技术专业级VDB插件实战指南从零掌握Unreal体积渲染技术 想要在Unreal Engine中实现电影级的烟雾、火焰和云朵效果吗Unreal VDB插件就是你测试移动开发质量保障开发工具SwiftSpinner高级技巧如何创建自定义进度指示器和动画效果SwiftSpinner高级技巧如何创建自定义进度指示器和动画效果 SwiftSpinner是一款用Swift编写的精美活动指示器和模态提醒组件专为iOS应上一篇终极命令行邮件管理工具Himalaya10分钟学会高效邮件处理下一篇推荐使用STYLIS - 轻量级CSS预处理器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
