react-native-windows 端到端测试实战:基于 WinAppDriver + WebDriverIO + Jest 的 e2e-test-app 体系
2026/9/21 15:18:06 网站建设 项目流程

react-native-windows 端到端测试实战:基于 WinAppDriver + WebDriverIO + Jest 的 e2e-test-app 体系

【免费下载链接】react-native-windowsA framework for building native Windows apps with React.项目地址: https://gitcode.com/gh_mirrors/re/react-native-windows

端到端测试是验证 react-native-windows 原生视图组件、交互行为与视觉渲染正确性的关键手段。本文基于仓库内 docs/e2e-testing.md 展开,围绕packages/e2e-test-app-fabric测试工程,完整讲解环境准备、测试运行、用例编写、快照测试与 CI 调试,并结合@react-native-windows/automationautomation-commands等源码包揭示底层运行机制。读完本文,你将掌握如何在本仓库中构建测试应用、编写针对 RNTester 示例页的 E2E 用例、进行视觉树与像素级快照比对,并在本地或 CI 中定位失败。

e2e-test-app 工程结构

E2E 测试应用、测试库与测试用例统一位于packages/e2e-test-app-fabric(对应仓库docs/e2e-testing.md中所称的 e2e-test-app),目录组织如下:

  • test—— 基于 Jest 与 WebDriverIO 编写的端到端测试用例,全部测试文件均以*.test.ts/*.test.js命名,例如 visitAllPages.test.ts、ViewComponentTest.test.ts;
  • windows—— UWP/WinAppSDK 原生应用工程(RNTesterApp-Fabric),包含.sln.vcxproj.appxmanifest等原生工程文件;
  • jest.config.js —— Jest 与 WebDriverIO 的统一配置入口,testEnvironment指向自定义环境@react-native-windows/automation

测试用例所依赖的辅助包包括:自定义 Jest 测试环境 @react-native-windows/automation(负责拉起 WinAppDriver、启动应用、建立 WebDriver 会话与 RPC 通道)、测试命令库 @react-native-windows/automation-commands(提供dumpVisualTreecreateScreenshot等命令)、以及 Windows 版 RNTester 页面集 @react-native-windows/tester。

环境准备与运行测试

安装 WinAppDriver v1.2.1

E2E 测试依赖 WinAppDriver v1.2.1。若使用仓库提供的依赖脚本 vnext/Scripts/rnw-dependencies.ps1 并以rnwDev为参数执行,WinAppDriver 会被自动安装。

测试默认假设 WinAppDriver 安装在默认位置:

C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe

若安装到其他路径,必须在 jest.config.js 的testEnvironmentOptions中显式指定winAppDriverBin

module.exports = { // ... testEnvironmentOptions: { // ... winAppDriverBin: 'D:\\Program Files (x86)\\Windows Application Driver\\WinAppDriver.exe', }, };

从 AutomationEnvironment.ts 的源码可见,环境构造时优先读取winAppDriverBin,否则回退到PROGRAMFILES(X86)环境变量下的默认路径;若该路径不存在会直接抛出Could not find WinAppDriver at searched location错误,因此路径配置错误会在测试启动阶段立即暴露。

构建原生测试应用

C:\repo\react-native-windows> cd packages\e2e-test-app-fabric C:\repo\react-native-windows\packages\e2e-test-app-fabric> yarn windows --no-launch

yarn windows对应 package.json 中的"windows": "npx @react-native-community/cli run-windows"--no-launch表示仅构建不启动应用。此外还可使用yarn bundle:debug生成调试用的 JS bundle(输出到windows/x64/Debug/RNTesterApp-Fabric/Bundle)。

运行全部测试

C:\repo\react-native-windows\packages\e2e-test-app-fabric> yarn start C:\repo\react-native-windows\packages\e2e-test-app-fabric> yarn e2etest
  • yarn start启动 Metro 打包服务(对应脚本"start": "npx @react-native-community/cli rnx-start");
  • yarn e2etest实际执行npx @react-native-community/cli rnx-test --platform windows,即以 Windows 平台运行 Jest 测试。

运行单个测试

C:\repo\react-native-windows\packages\e2e-test-app-fabric> yarn start

⚠ 只传入测试文件名(不含其余路径部分)。

C:\repo\react-native-windows\packages\e2e-test-app-fabric> yarn e2etest visitAllPages.test.ts

单个测试文件通过testRegex(见 jest.config.js 中的'.*\\.test\\.ts$''.*\\.test\\.js$')匹配,因此直接传文件名即可筛选。

应用启动时中断(Break on start)

C:\repo\react-native-windows\packages\e2e-test-app-fabric> yarn start C:\repo\react-native-windows\packages\e2e-test-app-fabric> yarn e2etest:debug visitAllPages.test.ts

yarn e2etest:debug对应脚本"e2etest:debug": "npx @react-native-community/cli rnx-test --platform windows --config ./jest.debug.config.js"。查看 jest.debug.config.js 可知,它只是在基础配置上设置了testEnvironmentOptions.breakOnStart = true;结合 AutomationEnvironment.ts 的实现,测试环境在建立 WebDriver 会话、应用窗口就绪后会以readlineSync.question阻塞并提示Breaking before tests start / Press Enter to resume...,方便你在此刻手动检查应用状态或附加调试器。

测试配置项详解

以下配置来自 jest.config.js,并对应 AutomationEnvironment.ts 中EnvironmentOptions的字段定义:

配置项当前值含义与取值范围
app'RNTesterApp-Fabric'要启动的应用,可为 exe 路径或包标识名;源码要求必填,否则环境构造直接抛错
useRootSessiontrue使用 Root(Desktop)会话再搜索应用窗口,打包的 WinAppSDK 应用必须开启
rootLaunchApptrue使用 Root 会话时是否仍由环境负责启动/关闭应用,设为false可挂接到已运行的实例
enableAutomationChanneltrue是否启用自动化 RPC 通道(默认端口 8603,可用automationChannelPort修改),用于ListErrors等命令
winAppDriverBin未设置WinAppDriver 可执行文件路径,默认C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe
breakOnStartfalse测试开始前是否中断等待回车,调试时由jest.debug.config.js开启
webdriverOptions注释掉透传给 WebDriverIO 的RemoteOptions,例如logLevel
appArguments/appWorkingDir未设置启动应用时附加的命令行参数与工作目录

环境中的其他关键默认值(源码 AutomationEnvironment.ts):WebDriver 服务地址为127.0.0.1:4723waitforTimeout默认 30 秒,connectionRetryTimeout默认 30 秒,connectionRetryCount默认 5 次;会话能力会附加ms:experimental-webdriver: true。同时 jest.config.js 中maxWorkers: 1保证串行执行,testTimeout: 70000(70 秒)作为单测例超时。

CI 中的测试调试

提高日志详细程度

默认情况下,测试只打印 WinAppDriver 返回的错误与断言失败信息。若想看到逐条 WebDriver wire 命令,可编辑 jest.config.js 的testEnvironmentOptions.webdriverOptions

module.exports = { // ... testEnvironmentOptions: { // ... webdriverOptions: { // Level of logging verbosity: trace | debug | info | warn | error logLevel: 'error', // ... }, }, };

logLevel支持trace | debug | info | warn | error五档,trace最详细。该配置最终通过Object.assign合并进 WebDriverIO 的RemoteOptions(见 AutomationEnvironment.ts),因此也可以在webdriverOptions中覆盖waitforTimeoutconnectionRetryTimeout等行为。

测试产物(Artifacts)

在 AzureDevOps 流水线中可获取以下构建产物用于排查崩溃与失败:

  • 测试失败时应用的错误截图(error screenshots);
  • test run XML—— 包含失败的 wdio 测试名与 JS 堆栈信息;
  • 树转储输出(tree dump outputs)—— 可将失败分支的输出与主干(main)分支对比,定位导致测试失败的差异;
  • e2e 测试应用(RNTesterApp)的崩溃转储(crash dumps)。

在 PR 对应的 AzureDevOps 运行中点击 artifacts 链接即可访问:

架构:三层协作

E2E 测试体系由三个组件协作完成,职责清晰:

WinAppDriver

WinAppDriver 使用 Windows UI Automation(UIA)来检查和操作被测应用,并对外暴露 W3C WebDriver 协议,使任意 WebDriver 客户端都能与之通信。测试过程中由 AutomationEnvironment.ts 负责将其作为子进程拉起(监听标准输出中的Press ENTER to exit.判定就绪),结束后以SIGINT关闭。

WebDriverIO

WebDriverIO 是 JavaScript 库,通过 WebDriver 协议连接 WinAppDriver。它提供查询应用 UI 树的全局 API(选择器)以及全局browser对象用于操作被测应用。测试环境中这些全局量被显式绑定到当前浏览器会话:this.global.browser = this.browserthis.global.$ = this.browser.$.bind(...)等(见 AutomationEnvironment.ts)。

Jest

Jest 是端到端测试的测试运行器,负责断言库、用例选择(testRegex)、超时与快照管理等。WebDriverIO 的设置由自定义环境 @react-native-windows/automation 提供(testEnvironment: '@react-native-windows/automation')。环境在setup()阶段依次完成:启动 WinAppDriver → 建立 Root 会话并轮询应用窗口(超时 5 分钟)→ 用真实窗口句柄替换appTopLevelWindow→ 建立 WebDriver 会话 →(可选)建立 automation channel RPC 连接;teardown()阶段则关闭 RPC 客户端、关闭窗口并结束会话。

编写测试用例

测试使用 Jest + WebDriverIO 编写,针对运行着RNTester的测试应用执行;RNTester示例页被作为测试 UI,由 Jest 测试逐一检查。测试应优先复用已有的RNTester页面,仓库中也存在只被 e2e-test-app-fabric 使用的 "Legacy" 自定义页面(见 test 目录 下的LegacyControlStyleTest.test.tsLegacyImageTest.test.ts等)。

针对 RNTester 示例页编写测试

// LegacyControlStyleTestPage.test.ts describe('FancyWidget', () => { beforeAll(async () => { await goToComponentExample('FancyWidget'); }); test('FancyWidget is populated with placeholder', async () => { // Query for an element with accessibilityId of "foo" (see "locators" below) const field = await app.findElementByTestID('foo'); expect(await field.getText()).toBe('placeholder'); }); });

其中goToComponentExample来自 RNTesterNavigation.ts:点击components-tab切换到 Components 标签页,在搜索框(explorer_search)输入示例名过滤列表后点击目标示例。源码特别处理了 WinAppDriver 对自定义 RN TextInput 输入时可能追加而非替换文本的问题——每次重试前先clearValue()setValue()并校验输入内容(见 RNTesterNavigation.ts)。

app对象来自 AutomationClient.ts,该文件同时定义了常用的定位器(locators)

方法底层选择器用途
findElementByTestID(id)$(`~${id}`)testID/ AccessibilityId 查找
findElementByAutomationID(id)$(`~${id}`)按 AutomationId 查找
findElementByClassName(className)$(className)按控件类名查找(如ListViewItem
findElementByControlType(type)$(`<${type} />`)按 ControlType 查找(如ButtonCheckBox
findElementByXPath(xpath)$(xpath)按 WinAppDriver 兼容 XPath 查找

此外app还提供窗口级操作:setWindowSize/setWindowPosition/getWindowSize/getWindowPositionswitchWindow以及通用等待waitUntil。返回的AutomationElement是对 WebDriverIO Element 的类型投影,包含clickgetTextsetValuewaitForDisplayedisDisplayedsaveScreenshot等常用方法。

实际测试中常将窗口固定到固定位置与尺寸以避免元素不可点击(例如 visitAllPages.test.ts 中的setWindowPosition(0,0)setWindowSize(1000,1250)),并在每个用例后用verifyNoErrorLogs()(见 Helpers.ts)通过 automation channel 调用ListErrors检查 JS 侧错误日志,实现“每页可访问 + 无红屏错误”的冒烟保障。

添加自定义 RNTester 页面

在新增自定义页面之前,请先评估能否直接修改已有的 RNTester 页面并向上游提交。如确需新增示例,可将其集成进 Windows 版 RNTester 分支 @react-native-windows/tester。文档推荐使用 Hooks 编写测试页面:

// ControlStyleTestPage.tsx export const title = 'LegacyControlStyleTest'; export const description = 'Legacy e2e test for Control Styles'; export const examples = [ { render: function(): JSX.Element { return <ControlStyleTestPage />; }, }, ];
// RNTesterList.windows.js ... { key: 'LegacyControlStyleTest', module: require('../examples-win/LegacyTests/ControlStyleTestPage'), }, ...

页面通过title/description/examples描述结构注册进 RNTester 列表;visitAllPages.test.ts会从@react-native-windows/tester/js/utils/RNTesterList动态读取全部 Components 示例并逐页生成用例(当前跳过FlyoutXAMLSwipeableCard三个已知不稳定页面,API 标签页用例被临时注释)。

快照测试(Snapshot Tests)

E2E 测试使用 Jest 的快照测试机制检测非预期的视觉变化。与针对 React 树做快照不同,e2e-test-app-fabric 比较的是完整渲染后的 composition 树,从而验证 ViewComponent 的渲染正确性:

import {dumpVisualTree} from '@react-native-windows/automation-commands'; test('Example test', async () => { const dump = await dumpVisualTree('test-id-here'); expect(dump).toMatchSnapshot(); });

dumpVisualTree由 @react-native-windows/automation-commands 提供(实现见 dumpVisualTree.ts)。快照文件保存在 test/__snapshots__ 目录下,例如ViewComponentTest.test.ts.snap

除了 composition 树快照,仓库还结合createScreenshotjest-image-snapshot做了像素级截图对比:Helpers.ts 中的verifyElementVisualSnapshot先取元素位置与尺寸,再调用createScreenshot(见 screenshot.ts)截图到临时目录,最后toMatchImageSnapshotfailureThreshold: 0.01(1% 像素差异容忍度)比对;截图基线存于 test/__image_snapshots__,例如view-component-test-test-ts-view-tests-visual-snapshot-of-views-with-shadows-2-snap.pngViewComponentTest.test.ts中即同时使用dumpVisualTreeverifyElementVisualSnapshot对阴影、边框、圆角、轮廓等样式进行双重校验。

更新快照有两种方式:

  1. 本地运行jest --updateSnapshot(对应脚本yarn e2etest:updateSnapshots,即rnx-test --platform windows -u);
  2. 从失败的 PR 上传的 "snapshots" 产物中复制新快照。

常见问题与排障要点

  • 找不到 WinAppDriver:确认已安装 v1.2.1 且路径与winAppDriverBin一致,环境构造阶段即会报错(AutomationEnvironment.ts)。
  • 找不到应用窗口:打包的 WinAppSDK 应用需开启useRootSession: true;环境会以 2 秒间隔轮询最多 5 分钟寻找Name === app的窗口,超时抛出Unable to find window(AutomationEnvironment.ts)。
  • 元素点击不稳定:将窗口固定到屏幕内并设置固定尺寸(setWindowPosition(0,0)setWindowSize(1000,1250));列表过长时先用搜索框过滤,避免元素在可视区域外。
  • 单测超时:默认testTimeout为 70 秒,冷启动或慢机器上可适当调大。
  • 快照大面积失败:先对比 tree dump 产物与主干分支的输出,定位差异来源后再决定是否更新快照。

以上全部内容均可在仓库中直接复现:环境与定位器实现见 packages/@react-native-windows/automation/src,测试命令与工具见 packages/@react-native-windows/automation-commands/src,完整用例见 packages/e2e-test-app-fabric/test。按“构建 → 启动 Metro → e2etest”三步即可在本仓库跑通整套 E2E 体系,为原生组件与渲染行为的回归验证提供可靠保障。

【免费下载链接】react-native-windowsA framework for building native Windows apps with React.项目地址: https://gitcode.com/gh_mirrors/re/react-native-windows

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

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

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

立即咨询