mcpField
W
writing-webdriverio-code

writing-webdriverio-code

github.com/klamping测试与质量539 次安装36 周前更新
代码仓库

关于 writing-webdriverio-code

Writing WebdriverIO Code 是将测试脚手架转为可执行 WebdriverIO 测试,并扩展或修复现有测试文件的技能。它遵循项目约定,强调确定性设置、稳健选择器和清晰断言。

主要功能

  1. 01实现脚手架中的测试场景
  2. 02扩展或修复现有测试文件
  3. 03遵循项目约定与上下文
  4. 04使用稳健选择器和显式等待
  5. 05设置隔离且确定的测试数据
  6. 06从根因排查不稳定测试

适用场景

  1. 01将伪代码注释转为可执行测试
  2. 02为现有 WebdriverIO 测试添加场景
  3. 03诊断并稳定不可靠的浏览器测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/klamping/webdriverio-skills --skill writing-webdriverio-code

安装后在 Claude Code 中输入/writing-webdriverio-code确认已加载。

详细介绍

编写 WebdriverIO 代码

将脚手架注释转换为可用于生产环境的测试代码。

此技能可以处理以下任一情况:

  • 由 creating-test-structure 创建的脚手架,或
  • 需要新增测试、重构或修复错误的现有 WebdriverIO 规范文件。

在这两种情况下,它都会生成具体的 WebdriverIO 实现,使其稳定、易读且便于调试。

适用场景

  • 已有脚手架,需要将伪代码转换为 WDIO 命令和断言。
  • 需要为现有测试文件添加其他场景。
  • 现有测试不稳定、脆弱或不正确,需要修复。

不适用场景

  • 需要根据 Markdown 测试计划为完整测试套件搭建脚手架(请使用 creating-test-structure)。
  • 仅需重新组织 describe/it 层级,不涉及代码实现。
  • 需要制定广泛的测试策略(测试金字塔/范围),而不是编写文件级别的 WDIO 代码。

输入约定

  • 带有伪代码注释的脚手架规范文件(可选)。
  • 或需要扩展/修复的现有已实现规范文件。
  • 项目中的现有页面对象、测试夹具和辅助工具。
  • 项目约定(代码检查、命名、断言风格)。

项目上下文文件

实现前,请在可用时读取项目缓存文件:

  • .webdriverio-skills/project-context.md
  • .webdriverio-skills/project-context.json
  • .webdriverio-skills/custom-rules.md
  • .webdriverio-skills/health-recommendations.md
  • references/website-analysis/<target>/website-analysis.md
  • references/website-analysis/<target>/website-analysis.json

将这些文件作为项目约定、脚本、环境用法和团队覆盖规则的默认依据。

使用网站分析参考资料了解路由/组件上下文、预期状态以及需要身份验证的流程。

<target> 应解析为小写的网站主机名(优先使用用户提供的 URL 或项目 baseUrl 主机名)。 如果无法获取,请使用 unknown-target,并继续使用其他上下文来源。

如果文件缺失或已过时,请先运行 managing-project-customizations。

转换工作流

  1. 确定目标是脚手架转换,还是直接增强/修复测试。
  2. 加载项目上下文和自定义规则,并将其作为硬性约束应用。
  3. 如果存在伪代码,按执行顺序实现注释内容。
  4. 优先使用现有页面对象方法,而不是创建新方法。
  5. 使用可靠的选择器和明确的预期。
  6. 行为明确后,移除伪代码注释。
  7. 仅保留用于解释非显而易见意图的注释。

套件启动状态卫生

  • 在套件启动时重置可能在测试间泄漏的状态(Cookie、本地存储、会话/身份验证状态)。
  • 确保启动前置条件具有幂等性,以便重复运行时得到相同的基准状态。
  • 优先在钩子中进行显式设置,避免依赖隐藏的跨测试状态。
  • 清理是必需的,但不要仅依赖可能因崩溃而无法运行的 after 钩子。

确定性测试数据的设置与清理

  • 尽可能通过 API/测试夹具创建确定性测试数据。
  • 为测试夹具/数据命名,使其用途一目了然。
  • 将设置逻辑放在需要它的测试范围附近(严格隔离时使用 beforeEach,共享稳定状态时使用 before)。
  • 始终为创建的数据提供清理路径。
  • 执行操作前,先在代码中验证测试数据的前提条件。

测试结构规则

  • 将每项测试划分为清晰的阶段:设置、验证、清理。
  • 共享设置逻辑应放在钩子中(before、beforeEach),不要复制粘贴到每项测试中。
  • 让每个 it(...) 专注于一种用户可观察到的行为。
  • 确保测试彼此独立,可单独运行,也可并行运行。

框架规则(Mocha/Jasmine)

  • 遵循项目中现有的 describe、it 和钩子风格。
  • 使用嵌套的 describe 块表示用户上下文,而非实现层级。
  • 如果扁平结构更易读,就避免过深的套件嵌套。
  • .only/.skip 仅用于本地调试,并在最终提交前移除。

页面对象规则

  • 将选择器和特定页面的操作放在页面对象/组件中。
  • 让测试规格专注于行为和断言。
  • 添加新抽象前,先复用现有页面对象方法。
  • 添加小型、用途明确的页面对象方法;避免使用包揽一切的通用辅助方法。

高效查询元素

  • 先将查询范围限定在有意义的容器中,再选择子元素。
  • 在一个测试步骤中复用已定位的元素,而不是反复查询同一选择器。
  • 优先使用唯一的语义化选择器,而非基于索引的查找。
  • 仅当 UI 约定明确规定位置顺序时,才使用基于索引的选择。

选择器规则

  • 优先使用面向用户的选择器:button=...、aria/...。
  • 当文本/ARIA 不稳定时,使用 data-testid。
  • 避免脆弱的类名链和与布局耦合的选择器。
  • 限定元素查询范围,以减少冲突。

等待规则

  • 尽可能依赖交互操作(click、setValue)的自动等待。
  • 对有意义的 UI 状态转换使用显式等待(waitForDisplayed、waitForClickable、waitUntil)。
  • 优先等待用户可见的结果,而非内部实现细节。
  • 不要将 browser.pause 用作同步策略。
  • 只有在受已知 UI 限制约束时(例如无法避免的动画时长),才允许使用短暂的硬等待;应少用并记录原因。
  • 除非有记录在案的理由,否则将隐式超时保持为默认值。
等待决策指南
情况首选方法避免
元素交互WDIO 自动等待 + 交互预先调用 pause
操作后的异步 UI 更新断言重试或 waitFor...固定休眠
非元素条件使用明确条件调用 browser.waitUntil(...)使用手动循环轮询
已知动画延迟仅在没有稳定信号时使用极短且有记录的 pause大范围使用长时间暂停

避免断言第三方依赖

  • 测试由应用自身负责的行为,而非外部提供商的内部机制。
  • 尽可能替身/模拟第三方集成,以避免外部不稳定因素。
  • 通过请求/响应处理来验证与外部服务之间的契约,而非验证供应商的正常运行时间或 UI。
  • 仅在必要时,为外部集成路径保留极少量的冒烟检查。

断言规则

  • 断言用户可见的结果和关键状态。
  • 使用 expect-webdriverio 匹配器(toHaveText、toBeDisplayed、toHaveUrlContaining)。
  • 选择明确的断言目标,以便提供有意义的失败信息。
  • 当行为依赖顺序时,明确断言列表的数量/顺序。
  • 仅验证与场景相关的行为;避免过多且冗余的断言。

测试命名规则

  • 测试名称应清楚描述行为。
  • 使用用户和开发者熟悉的领域术语。
  • 避免含糊的名称(should work、happy path test)。
  • 根据预期结果命名测试,而非实现步骤。

安全规则

  • 切勿硬编码机密信息。
  • 输入凭据时屏蔽敏感值(在支持的情况下使用 setValue(..., { mask: true }))。
  • 避免在日志中泄露令牌或凭据。

编写便于快速调试的测试

  • 按执行顺序编写清晰易读的测试步骤。
  • 使用能清楚指出失败原因的断言目标,无需额外排查。
  • 对复杂流程添加简洁的步骤级日志。
  • 让测试规格中的抽象保持浅层,以便快速将失败对应到测试意图。

不稳定测试排查手册

  1. 稳定复现失败(先运行单个测试,再重复运行)。
  2. 隔离不稳定的步骤(选择器、等待、数据、环境或共享状态)。
  3. 对根本原因进行分类(时机、状态泄漏、脆弱的定位器、测试数据漂移、外部依赖)。
  4. 修复根本原因(不要用休眠/重试来掩盖问题)。
  5. 关闭问题前多次重新运行,以验证稳定性。

快速参考

测试意图典型 WDIO 实现
导航到页面await browser.url('/path')
与控件交互await el.click() / await el.setValue(...)
验证可见结果await expect(el).toBeDisplayed()
验证内容/状态await expect(el).toHaveText(...) / toHaveValue(...)
等待异步状态变化await el.waitForDisplayed() 或 browser.waitUntil(...)

常见错误

  • 认为始终需要脚手架。
  • 留下未实现的伪代码注释。
  • 将注释转换为脆弱的选择器。
  • 使用 browser.pause,而不是等待某个条件。
  • 过度使用会掩盖测试意图的辅助抽象。
  • 将测试与执行顺序耦合。
  • 将重试视为根因修复的替代方案。

示例

it('should default to showing the global feed', async function () {
  const activeTabs = await $$('.feed-toggle .nav-link.active');
  await expect(activeTabs).toBeElementsArrayOfSize(1);
  await expect(activeTabs[0]).toHaveText('Global Feed');
});

完成的标准是:所有伪代码注释都已转换为易于维护的 WDIO 代码,或仅为说明不明显的上下文而有意保留。

评论

支持 Markdown