尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

WebdriverIO Shared Store Service 实战指南:跨进程共享数据与资源池管理

WebdriverIO Shared Store Service 实战指南:跨进程共享数据与资源池管理 WebdriverIO Shared Store Service 实战指南跨进程共享数据与资源池管理【免费下载链接】webdriverioNext-gen browser and mobile automation test framework for Node.js项目地址: https://gitcode.com/GitHub_Trending/we/webdriverioWebdriverIO 的wdio/shared-store-service提供了一套轻量级的跨进程数据交换方案让主进程launcher与所有 worker 进程各 spec 测试之间能够共享键值数据并支持“资源池”机制为多个并发 worker 分配互斥的唯一资源。读完本文你将掌握如何在wdio.conf.js钩子与测试用例中通过browser.sharedStore、setValue/getValue读写共享存储以及如何用 Resource Pool API 实现类似“多 worker 各占用一个独立 URL”的调度场景并了解其底层基于 polka HTTP 服务与 capability 透传的实现原理。什么是 Shared Store ServiceWebdriverIO 的运行模型是主进程launcher多个 worker 进程每个 spec 文件会在独立的 worker 进程中执行进程之间默认没有共享内存。wdio/shared-store-service解决的是这类**进程间通信IPC**需求——例如在onPrepare中生成一批环境参数让每个 spec 都能读取或在不同测试之间传递由环境初始化得到的唯一值。官方定位READMEExchange data between main process and workers (specs)。它的核心能力包括键值存储通过字符串 key 写入/读取任意 JSON 兼容的普通对象plain object保留键*一次性读取整个存储Resource Pool API从预置的资源数组中取出一个元素取出后从池中移除用完后可归还保证并发 worker 不会拿到同一个资源钩子直连无需测试环境直接在wdio.conf.js的钩子函数中调用setValue/getValue等异步方法。当前仓库中该包的版本为 9.31.9见 package.json要求 Node.js18.20.0同时具备 ESMimport与 CJSrequire双入口。安装把wdio/shared-store-service作为 devDependency 安装到你的项目中npm install wdio/shared-store-service --save-devWebdriverIO 本身的安装指引参考 GettingStarted。安装完成后在wdio.conf.js的services列表中加入shared-store// wdio.conf.js export const config { // ... services: [shared-store], // ... };配置后browser.sharedStore对象会在测试用例中自动可用。架构与工作原理一个进程内的本地 HTTP 服务要正确地使用该服务理解它的运行机制很有帮助。从源码看它由三部分组成1. launcher启动服务并广播端口主进程launcher.ts 在主进程的onPrepare阶段执行动态import(./server.js)启动一个 polka HTTP 服务监听127.0.0.1的随机端口0表示由操作系统分配空闲端口见 server.ts调用setPort(port)把端口写入客户端的baseUrlPromise把端口以自定义 capabilitywdio:sharedStoreServicePort定义在 constants.ts注入到每一组 capabilities中这样每个 worker 都能获知服务地址在onComplete阶段关闭服务。launcher 的单元测试快照launcher.test.ts.snap验证了它对四种 capabilities 形态的注入逻辑普通 caps、W3C 的alwaysMatch、multiremotebrowserA/browserB以及并行 multiremote 数组。2. service把sharedStore挂到browser上worker 进程service.ts 在每个 worker 中从 capabilities 里读取wdio:sharedStoreServicePort支持 W3C 形态与 multiremote 形态找不到端口会抛出SharedStoreService: port not found in capabilities在before钩子中为browser.sharedStore绑定get、set、setResourcePool、getValueFromPool、addValueToPool五个方法对 multiremote 场景会把同一个sharedStore对象同步绑定到每个远程 browser 实例上browser.instances.forEach(...)。3. client基于 fetch 的 HTTP 客户端client.ts 用原生fetch与服务端通信处理一个关键时序问题用户可能在服务端口就绪前如onPrepare钩子就调用setValue。此时baseUrlPromise尚未 resolvesetValue/setResourcePool会先把请求挂起到 Promise 上待setPort触发后再 flush 发出——测试用例 client.test.ts 明确验证了这一缓冲行为。而getValue、getValueFromPool、addValueToPool在服务未初始化时会直接抛出Attempting to use ... before the server has been initialized.错误。服务端 server.ts 内置两个存储结构普通键值store: JsonObject和资源池resourcePoolStore: Mapstring, JsonArray并通过 polka 的json()中间件解析请求体。读写共享值在测试用例中通过browser.sharedStore读写// 写入key 为字符串value 为 JSON 兼容的普通对象 await browser.sharedStore.set(key, foobar123) // 读取 const value await browser.sharedStore.get(key) console.log(value) // 输出 foobar123也可以一次性获取整个存储使用保留键*const store await browser.sharedStore.get(*) console.log(store) // 输出 { key: foobar123, ... }几点行为细节与源码一一对应key 为任意字符串但*被保留。服务端在POST /路由中若发现 key 为*会直接抛出You cant set a value with key * as this is a reserved keyserver.ts读取不存在的 keyGET /:key返回{ value: undefined }客户端getValue通过responseBody.value ?? undefined返回undefinedvalue 的类型set接受JsonPrimitive | JsonCompatible字符串、数字、布尔、null、数组、普通对象等get返回string | number | boolean | JsonObject | JsonArray | null | undefined类型定义见 index.ts 与 client.ts。在 WDIO 钩子中直接访问除了通过browser.sharedStore还可以直接在wdio.conf.js中导入并调用异步方法setValue、getValue注意必须配合await// wdio.conf.js import { setValue, getValue } from wdio/shared-store-service export const config { // ... onPrepare: [async function (config, capabilities) { await setValue(foo, bar) }], // ... after: async () { const value await getValue(foo) // 处理 value... } // ... }onPrepare中调用setValue之所以可行正依赖前文所述的baseUrlPromise缓冲机制——服务其实是由 launcher 的onPrepare启动的用户自定义钩子可能先于它执行此时请求会被缓存待端口就绪后自动发出。包的入口index.ts统一导出了这五个函数setValue、getValue、setResourcePool、getValueFromPool、addValueToPool同时为 CommonJS 用户提供了一份转发包装 index.cts。⚠️ 重要约束每个 spec 文件应当是原子化atomic且相互隔离的。该服务的定位是解决特定的环境初始化问题官方明确告诫请避免用它共享测试执行数据见 README。Resource Pool为并发 worker 分配互斥资源当多个 worker 线程竞争同一类资源每个 worker 必须分配到独一无二的一份时可使用 Resource Pool API。典型场景多个浏览器实例都需要一个可用的测试 URL且彼此不能重复。// wdio.conf.js import { setResourcePool, getValueFromPool, addValueToPool } from wdio/shared-store-service export const config { maxInstances: 2, // ... onPrepare: async function (config, capabilities) { // 预置资源池 await setResourcePool(availableUrls, [url01.com, url02.com]) }, // ... beforeSession: async (conf) { // 每个 worker 取走一个唯一 URL 作为自己的 baseUrl conf.baseUrl await getValueFromPool(availableUrls) }, // ... afterSession: async (conf) { // worker 结束后把用过的资源归还供其他 worker 复用 await addValueToPool(availableUrls, conf.baseUrl) } // ... }这个例子确保两个 worker永远不会拿到相同的baseUrl一个 URL 在分配给某个 worker 期间是唯一的直到该 worker 释放它。这在类似“每个 worker 独占一个登录账号、一台测试设备、一个子域名”的场景中非常实用。资源池的底层行为理解以下实现细节能帮助你用好它均出自 server.ts创建池setResourcePool(key, value)通过POST /pool创建value必须是数组否则服务端返回Resource pool must be an array of values取出资源getValueFromPool(key, options)通过GET /pool/:key获取。池中有元素时立即shift()返回并移除超时等待池为空时不会立刻报错而是等待一段时间后重试。超时通过options.timeout毫秒控制默认DEFAULT_TIMEOUT 1000ms且会被钳制到最大值MAX_TIMEOUT 15000msMath.min(...)。等待期间如果其他 worker 归还了资源则会取到该资源否则抛出key resource pool is empty. ...错误归还资源addValueToPool(key, value)通过POST /pool/:key把值push回池尾部。若该 key 的池尚不存在服务端会返回key resource pool does not exist. Set it first using setResourcePool同样的方法也以browser.sharedStore.setResourcePool / getValueFromPool / addValueToPool的形式暴露在测试作用域内见 service.ts。配置与 TypeScript 类型基础配置在wdio.conf.js中声明服务即可// wdio.conf.js export const config { // ... services: [shared-store], // ... };TypeScript 支持如果你使用 TypeScript需要在tsconfig.json的compilerOptions.types中加入该包以便browser.sharedStore等类型自动生效{ compilerOptions: { types: [node, wdio/globals/types, wdio/shared-store-service] } }包的模块声明index.ts通过declare global为WebdriverIO.Browser与WebdriverIO.MultiRemoteBrowser扩展了sharedStore接口包含get、set、setResourcePool、getValueFromPool、addValueToPool五个方法签名分别与JsonPrimitive | JsonCompatible、JsonArray、GetValueOptions等类型对应。限制与适用前提要求 Node.js18.20.0原生fetch可用见 package.json服务运行在127.0.0.1随机端口上仅本机进程间可用不适用于跨机器/跨网络的集群场景服务端存储于内存中随测试进程生命周期结束而销毁请在onComplete阶段确认服务正常关闭launcher 已内置处理见 launcher.ts。小结与最佳实践能力用法适用场景键值存储browser.sharedStore.set/get环境初始化参数在 spec 间共享钩子直连import { setValue, getValue }在onPrepare/after等钩子中读写批量读取get(*)调试或一次性导出全部数据资源池setResourcePool/getValueFromPool/addValueToPool多 worker 分配互斥的唯一资源最佳实践总结仅用于环境/配置层面的共享不要把测试数据、断言结果塞进 store保证 spec 的原子性与隔离性资源池场景记得在afterSession或测试结束中归还资源避免后续 worker 拿不到值若在onPrepare之前调用读取类方法会得到“server has not been initialized”错误请把初始化依赖放在onPrepare钩子中结合 TypeScript 时务必把wdio/shared-store-service加入compilerOptions.types以获得完整的类型提示。作为跨进程数据交换的官方方案wdio/shared-store-service用极简的 API 覆盖了测试框架中最常见的一类痛点——主进程与 worker 之间的环境信息同步值得在你的多 spec、多实例测试套件中按需采用。【免费下载链接】webdriverioNext-gen browser and mobile automation test framework for Node.js项目地址: https://gitcode.com/GitHub_Trending/we/webdriverio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表