news 2026/9/12 13:10:07

如何为 Comprehensive Rust 的 tests 目录编写避免状态泄漏与竞态条件的 WebdriverIO 测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何为 Comprehensive Rust 的 tests 目录编写避免状态泄漏与竞态条件的 WebdriverIO 测试

如何为 Comprehensive Rust 的 tests 目录编写避免状态泄漏与竞态条件的 WebdriverIO 测试

【免费下载链接】comprehensive-rustThis is the Rust course used by the Android team at Google. It provides you the material to quickly teach Rust.项目地址: https://gitcode.com/GitHub_Trending/co/comprehensive-rust

Comprehensive Rust 的课程网站(theme/下的book.jsspeaker-notes.js等 JS 代码)依赖真实浏览器行为来验证功能,因此项目的tests/目录用 WebdriverIO 搭配 Mocha 和 WebdriverIO Expect API 编写端到端测试。新写或维护测试时最容易遇到两个问题:前一个测试留下的状态(如 JavaScript 写入的行内样式、sessionStorage)泄漏到下一个测试,以及页面元素由 JavaScript 在初始加载后动态生成、测试提前访问导致的偶发失败。这篇文章给出仓库中实际使用的两类写法,并说明如何运行和验证。

测试环境有两个配置,写新测试时默认走前者:

  • npm test(对应 wdio.conf.ts):通过@wdio/static-server-servicelocalhost:8080起临时静态服务器,自包含,大多数测试开发应使用它。
  • npm run test-mdbook(对应 wdio.conf-mdbook.ts):面向本地cargo xtask serve起的http://localhost:3000实例,只覆盖了baseUrl并清空services,仅用于对本地服务快速迭代。

准备条件

按 GEMINI.md 的项目约定:

# 1. 安装 Rust(rustup),克隆仓库后执行: cargo xtask install-tools

cargo xtask install-tools会安装项目依赖的工具,包括固定的 nightly 工具链(nightly-2025-09-01)、mdbook 及其 Bazel 构建的预处理器插件。没有这一步,后续的构建与测试无法正常工作。

wdio.conf.ts中与稳定性相关的默认值(写测试时可依赖这些行为):

  • baseUrl: "http://localhost:8080",静态服务器挂载env.TEST_BOOK_DIR || "../book/html"
  • waitforTimeout: 10000:所有waitFor*命令的默认超时;
  • mochaOpts.timeout: 60000:单个 Mocha 测试的超时;
  • Chrome capabilities 默认只带--headless;当CI环境变量存在时,会追加--disable-gpu--no-sandbox--disable-dev-shm-usage等标志以提升 CI 稳定性。

用 beforeEach 中的 browser.refresh() 消除测试间状态泄漏

redbox.test.ts中的 测试 展示了本仓库确认有效的做法。直接调用browser.url()并不能保证干净的起点:JavaScript 施加的行内样式等残留状态可能从一个测试带到下一个,造成难以解释的失败。redbox.test.ts的注释明确写着:按 WebdriverIO 文档这“本不应该必要,但没有它测试会失败”。完整的beforeEach如下:

beforeEach(async () => { await browser.url("/hello-world.html"); await browser.execute(() => sessionStorage.clear()); // Clear any lingering state (like inline styles) from previous // tests. Reading https://webdriver.io/docs/api/browser/url, // this should not be necessary, but tests fail without it. await browser.refresh(); });

即导航到被测页面后,先清掉sessionStorage(该功能用showRedBox键持久化状态,不清会让“默认隐藏”“URL 参数覆盖”这类断言互相污染),再refresh()强制整页重载以清掉行内样式等残留状态。speaker-notes.test.ts 的beforeEach同样是browser.url(...)后紧跟browser.refresh(),而它的afterEach还负责关闭测试中打开的新窗口,避免句柄泄漏到后续测试:

afterEach(async () => { const handles = await browser.getWindowHandles(); if (handles.length > 1) { await browser.switchToWindow(handles[1]); await browser.closeWindow(); await browser.switchToWindow(handles[0]); } });

用等待与自定义命令消除竞态条件

本页面的很多元素由 JavaScript 在初始加载后动态创建。如果测试在导航后立即访问,脚本可能还没跑完、元素尚不在 DOM 中。GEMINI.md 给出的规则是:在对动态元素交互或断言(如toBeDisplayed())之前,始终先await element.waitForExist()

另一类竞态出现在模拟键盘等操作之后。wdio.conf.ts 的before钩子里注册了自定义命令toggleRedBox,注释说明原因:直接的browser.keys()调用“被证明是不稳定的,会造成间歇性测试失败”。该命令用waitUntil等待 UI 真正反映状态变化,从而消除竞态:

browser.addCommand("toggleRedBox", async function () { const redBox = await $("#aspect-ratio-helper"); const initialVisibility = await redBox.isDisplayed(); // Perform the toggle action. await browser.keys(["Control", "Alt", "b"]); // Wait until the visibility state has changed. await browser.waitUntil( async function () { const currentVisibility = await redBox.isDisplayed(); return currentVisibility !== initialVisibility; }, { timeout: 5000, timeoutMsg: `Red box display state did not toggle after 5s. Initial state: ${initialVisibility}`, }, ); });

如果你的被测功能也有“操作后状态异步变化”的形态,照这个模式写自定义命令(操作 +waitUntil轮询目标状态),比在断言前硬编码等待更可靠。

导航一律使用最终的非重定向 URL

book.toml 在[output.html.redirect]段定义了一张重定向表,例如"async.html" = "concurrency/welcome-async.html",大量旧路径会 301 到新的课程结构。GEMINI.md 的警告是:导航到重定向 URL 虽然浏览器会跟随,但这个过程会丢掉 URL 查询参数,导致依赖参数的功能测试失败。所以写测试时导航目标一律用重定向表右值那侧的最终页面。redbox.test.ts里用/hello-world.html?show-red-box=true验证 URL 参数行为,就是针对最终 URL 写的;而book.toml中确实存在"welcome-day-1/what-is-rust.html" = "../hello-world/what-is-rust.html"这类条目,若导航到旧路径?show-red-box=true之类的参数就会在跳转中丢失。

运行测试与验证稳定性

tests/目录下运行:

# 运行全部 spec(静态服务器模式,端口 8080) npm test # 只运行文件名匹配 redbox 的 spec npm test -- --spec redbox # 只运行文件内单个用例(Mocha grep) npm test -- --spec redbox --mochaOpts.grep "should be hidden by default" # 用重复执行检查偶发性 npm test -- --spec redbox --repeat 100

仓库根目录下等价的入口是cargo xtask web-tests,可选--dir <book_html_directory>指定构建产物目录(它会同时刷新slide-style-guide.test.ts使用的幻灯片列表);本地快速迭代时也可以cargo xtask serve起 3000 端口服务后改用npm run test-mdbook

验证标准:

  1. npm test全部用例通过;
  2. --repeat(如 100 次)重复跑改动过的 spec,确认无偶发失败;
  3. 在设置CI环境变量的条件下跑一遍,确认追加的 Chrome 标志下依然通过。

区分功能失败与环境故障

按 tests/README.md 的说法,失败先分两类:

  • 合理告警(Legitimate warnings):例如页面过长需要缩短或申请豁免,或 mdbook 基础设施的破坏性变更打断了功能。这类问题必须在合并前修复。
  • 测试环境损坏(Broken test environment):CI 中出现如ERROR webdriver: WebDriverError: tab crashed的报错时,可能不是你的改动导致的。此时应提交 bug 报告;若其余检查都通过且你确信改动正确,可以绕过 web-test 要求合并 pull request 作为临时措施。

新测试写完后的落点就是上面三件事:beforeEach里带refresh()的状态清理、动态元素先waitForExist()(异步状态用waitUntil封装成自定义命令)、导航只认最终 URL,最后用--repeat证明没有 flakiness 再提交。

【免费下载链接】comprehensive-rustThis is the Rust course used by the Android team at Google. It provides you the material to quickly teach Rust.项目地址: https://gitcode.com/GitHub_Trending/co/comprehensive-rust

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 13:09:17

ABAQUS在埋地管道滑坡与沉降分析中的应用

1. 滑坡与沉降对埋地管道影响的工程背景埋地管道作为能源输送和市政基础设施的关键组成部分&#xff0c;其安全运行直接关系到国民经济和公共安全。在实际工程中&#xff0c;管道常常需要穿越地质条件复杂的区域&#xff0c;特别是山区、河谷等地质灾害多发地带。滑坡和地面沉降…

作者头像 李华
网站建设 2026/9/12 13:09:00

ESP8266接入MQTT协议实战:从搭建Broker到远程控制设备

我先把话放在前面&#xff1a;这篇是系列里的第三篇&#xff0c;如果你已经跟着前两篇把ESP8266的开发环境、基础外设玩明白了&#xff0c;那MQTT这部分就是你从“玩板子”跨到“做物联网项目”最关键的一步。如果前面还不太熟&#xff0c;也没关系&#xff0c;这篇文章会把MQT…

作者头像 李华
网站建设 2026/9/12 13:08:49

CookLikeHOC 鸡汤娃娃菜:用标准化老鸡汤汆烫工艺复刻老乡鸡烫菜出品

CookLikeHOC 鸡汤娃娃菜&#xff1a;用标准化老鸡汤汆烫工艺复刻老乡鸡烫菜出品 【免费下载链接】CookLikeHOC &#x1f962;像老乡鸡&#x1f414;那样做饭。已添加2026年发布的《老乡鸡菜品溯源报告 2.0中新出现的菜品。主要部分于2024年完工&#xff0c;非老乡鸡官方仓库。文…

作者头像 李华
网站建设 2026/9/12 13:07:24

「AI Agent 全栈开发 50 讲」——从本地模型部署到多智能体系统,一年省 87 万 第 32 课 | LlamaIndex 入门:用 50 行代码构建企业级知识库

第 32 课 | LlamaIndex 入门&#xff1a;用 50 行代码构建企业级知识库 从零到一&#xff1a;用 LlamaIndex 将行业报告、研究文档构建为可语义检索的知识库&#xff0c;让 Agent 的回答有据可依。 一、业务痛点&#xff1a;Agent 的「知识幻觉」问题 在场景二中&#xff0c;我…

作者头像 李华
网站建设 2026/9/12 13:06:38

LabVIEW测试系统开发:商用价值与工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华