关于 refactoring-codeceptjs-tests
这是一个在保持行为不变的前提下重构 CodeceptJS 4 测试的技能。它帮助团队将重复 UI 流程、定位器和浏览器逻辑移至合适的页面对象、Actor 步骤或自定义 Helper,并在分批修改间提案和验证。
主要功能
- 01查找重复流程和冗长定位器
- 02将流程移至页面对象或 Actor 步骤
- 03把原始浏览器逻辑提取为自定义 Helper
- 04应用前按目标文件分组提案
- 05每批修改后重跑受影响的 Scenario
适用场景
- 01整理重复的 UI 测试步骤
- 02减少测试中的定位器重复
- 03将浏览器或数据准备逻辑移出 Scenario
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ codeceptjs/ skills --skill refactoring-codeceptjs-tests安装后在 Claude Code 中输入/refactoring-codeceptjs-tests确认已加载。
详细介绍
重构 CodeceptJS 4 测试
测试套件会以三种可预测的方式逐渐变差:在多个文件中复制粘贴重复的 UI 流程,到处重复臃肿的定位器,以及在场景中混入原始 JS。针对每种情况,解决办法都是将模式移到合适的位置,同时不改变行为。
适用于定向(用户指定的文件或场景)或全局(整个已配置的 tests glob)。无论哪种方式,都要先提出方案,获批后再分批应用,以便审查。
工作流
- 基础知识 — 运行
codeceptjs-fundamentals。你需要了解:include下的页面对象、actor 文件、自定义 helper 和 auth roles。否则你不知道提取出的内容该放在哪里。 - 选择范围:
- 定向 — 读取一次,提出方案,然后应用。
- 全局 — 多轮循环:清点 → 分组提出方案 → 获批 → 应用一批 → 重新运行受影响的场景 → 进入下一批。绝不要一次性进行大规模编辑。
- 清点 — 标记以下内容:
- 在 2 个或更多场景中重复出现的
I.*序列 - 在 2 个或更多位置使用的定位器;多行 XPath/深层嵌套 CSS
- 未限定作用域且包含自身区域信息的定位器(
'.sidebar nav a.settings')、'aria-label=X'写法,以及调用处的原始[data-testid=...] - 多语句
I.executeScript;执行业务操作的usePlaywrightTo/usePuppeteerTo/useWebDriverTo - 硬编码的凭据、URL、固定字符串
I.wait(N)和普通操作上多余的await—— 顺手修复
- 在 2 个或更多场景中重复出现的
- 重复流程 → 页面对象方法 — 方法名应体现用户意图(
loginPage.signIn(email, pass)、cartPage.removeItem(name))。遵循三次原则:第二次出现时就提取;只出现一次的代码保留原处。 - 臃肿的定位器 — 在考虑使用构建器之前先拆分:结构部分作为上下文参数,其余部分保留为语义字符串。
I.click('.sidebar nav a.settings')→I.click('Settings', '.sidebar')I.click({ css: '[aria-label="Save"]' })→I.click('Save', '.toolbar')I.click({ css: '[data-qa=submit]' })→ 配合customLocator使用I.click('$submit', '.checkout')只有拆分后仍需保留的内容才需要locate():只使用一次 → 在调用处内联;使用 2 次或更多 → 保存为带有.as('description')的具名 PO 字段,让失败信息指向有意义的名称。
- 原始 JS → 自定义 helper —
I.executeScript代码块、执行 DOM 遍历或业务逻辑的usePlaywrightTo,以及场景中的手写 fetch 请求。记住基础知识中的规则:helper 内不存在I—— 通过this.helpers['<Name>']组合调用。测试中仍使用I.*这套词汇。 - 重复登录逻辑 — 不要构建
loginPage.signIn方法。交给codeceptjs-auth:这正是auth插件存在的原因。适用会话复用时,登录 PO 就是一种坏味道。 - 全站操作(
I.acceptCookies()、I.goToBilling())— 放在 actor 文件(custom_steps.js),而不是任何单个页面的 PO 中。没有任何单个页面拥有该操作时,这才是合适的位置。
决策树
| 模式 | 放置位置 |
|---|---|
| 单个页面上的 UI 流程 | 该页面 PO 上的方法 |
| 跨页面、全站范围的 UI 流程 | Actor(custom_steps.js) |
| 登录 | auth 插件(参见 codeceptjs-auth) |
| 包含自身区域信息的长定位器 | 简短的语义定位器 + 上下文参数 |
| 只使用一次的长定位器 | 内联使用 locate() |
| 使用 2 次或更多的长定位器 | 将 locate() 保存为 PO 字段 |
| 原始浏览器 API/文件系统/数据库/邮件 | 自定义 helper |
| 通过 API 设置测试数据 | REST helper + Data Object |
先提出方案,再应用
按目标文件分组提出方案(pages/loginPage.js、helpers/DbHelper.js、tests/checkout_test.js)。编辑前展示清单。全局模式下:明确获批后,每批处理 3 到 5 个文件,并在每批后重新运行:
npx codeceptjs run --grep '<scenario or feature>' --steps
将输出交给 codeceptjs-run-analysis —— 确认每个受影响的场景仍然通过,且没有失败转移到新的步骤上。没有运行验证的重构不算重构。
应避免的事项
- 重构后未重新运行受影响的场景。
- 提取只使用一次的流程——等它第二次出现时再提取。
- 重命名 PO 方法/字段前,未使用 grep 搜索所有调用处。
- 明明页面对象就能胜任,却使用自定义辅助工具。
- 将不同的流程合并为一个方法(
loginPage.do(thing)是一种不良信号)。 - 修改场景名称或标签——CI 和
--grep会引用它们。 - 在全局模式下批量应用更改,却不分批处理和重新运行。
相关技能
codeceptjs-fundamentals— 主要规则、内容归属、架构(“I”不可达规则)codeceptjs-auth— 登录去重codeceptjs-run-analysis— 重构后的验证
评论
支持 Markdown