PlaywrightBDD步骤定义技能:让 Gherkin 步骤一键变成类型安全的 Playwright 代码
- 它是什么:一个专用于生成 Playwright BDD「步骤定义(Step Definitions)」的 AI 技能,核心是用
createBdd()生成类型安全的Given / When / Then函数。 - 它能解决什么:Gherkin 特征文件写好了、步骤代码却要一条条手写,还要处理参数类型、fixtures 复用、Page Object 集成——这个技能把这些重复劳动交给 AI。
- 覆盖范围广:内置参数(
{string}{int}{float}{word})、匿名正则参数、自定义参数类型、自定义 fixtures、装饰器写法、DataTable 三种解析方式、Doc Strings、跨步骤共享状态(World),都有对应范例。 - 适合谁用:正在落地或迁移 Playwright BDD 的前端测试工程师、QA、需要维护自动化回归套件的研发团队。
- 一句话结论:它不是"又一个测试框架",而是一份可被 AI 调用的专家知识,把 BDD 步骤层的写法标准化、模板化。
该技能叫什么?如何下载安装 AI 技能提升开发效率?
基本信息
| 项目 | 内容 |
|---|---|
| 技能中文名 | PlaywrightBDD步骤定义技能Skill |
| 技能英文名 | playwright-bdd-step-definitions |
| 技能ID | 13923 |
| 技能类型 | 知识型/参考型技能,提供 Playwright BDD 步骤定义的专家级写法指导 |
| 可用工具(技能声明) | Read、Write、Edit、Bash、Glob、Grep |
| 调用方式 | 声明为不可由用户直接调用(user-invocable: false),通常由主流程或上层技能自动引用 |
从技能声明可以看到,它的定位是一份"专家知识包":描述中明确写着「用于使用 createBdd() 创建步骤定义函数,实现 Page Object Model 模式,并在步骤之间共享 fixtures」。也就是说,它并不会替你做测试决策,它提供的是"怎么写对、怎么写好"的范式与可复用代码结构。
它到底解决什么问题
在没有这类技能辅助时,用 Playwright + BDD 落地一个中型项目,通常会反复遇到以下痛点:
- 步骤定义样板代码多:每个
Given/When/Then都要手动引入createBdd()、拆解参数、补类型标注,写十几次之后就很难保证风格统一。 - 参数类型混乱:同一条「我等待 N 秒」的步骤,有人用
{int},有人写正则捕获组,还有人直接把参数当字符串用,导致类型不安全。 - fixtures 越写越乱:登录态、页面对象、API 客户端各自扩展一份
test,最后createBdd()该传哪个test都记不清。 - 跨步骤共享状态没有统一方案:上一个步骤创建的数据,下一个步骤验证时拿不到,只能靠全局变量。
- 从 Cucumber 迁移过来无从下手:老的
World、DataTable、Doc String 写法在 Playwright BDD 里怎么对应,需要逐个摸索。
这个技能就是围绕这五类痛点组织的知识:它把「基本步骤函数 → 参数类型 → 自定义 fixtures → Page Object Model → 装饰器 → 数据表格 → Doc Strings → 状态共享 → 错误处理 → 最佳实践」串成了一条完整路径。
一键安装 AI 技能提升开发效率的思路
AI 技能的安装思路与普通 npm 包不同:它通常是通过技能平台/技能市场导入到你的 AI 编程助手中,之后由助手在合适的时机自动加载这份知识。具体步骤如下:
第一步:确认前置条件
- 需要具备一个支持「技能(Skill)」机制的 AI 编程助手或 IDE 插件环境(具体支持范围以官方说明为准)。
- 需要有一个已经使用 Playwright 的前端工程,并已引入
playwright-bdd依赖;同时具备 Node.js 与 TypeScript 环境。 - 建议工程内已有
features/(特征文件)与steps/(步骤定义)目录结构,便于技能产出的代码直接落位。
第二步:在技能市场搜索并安装
在技能平台的搜索框中输入技能英文名 playwright-bdd-step-definitions,或直接按技能ID 13923 定位,然后点击安装/启用。技能导入后一般会写入本地技能目录,技能名称、描述、可用工具等信息来自其 SKILL.md 元数据。若你的平台提供命令行安装入口,命令格式与参数以官方说明为准。
第三步:验证技能是否生效
安装完成后,在对话中提出一个具体的、只与该技能领域相关的问题来"探针测试",例如:
「帮我写一个 Playwright BDD 的步骤定义:Given 我以 {string} 身份登录,并在步骤之间用自定义 fixture 复用登录态。」
如果技能已生效,回答应当具备以下特征:
- 出现
import { createBdd } from 'playwright-bdd'与const { Given, When, Then } = createBdd();这样的标志性结构; - 参数使用
{string}、{int}等内置类型并带 TypeScript 类型标注; - 涉及登录态时,会给出
base.extend()扩展 fixtures、再用createBdd(test)生成步骤函数的两段式写法。
若回答只是泛泛的 BDD 概念介绍、没有出现 createBdd(),说明技能未被加载,可以检查技能是否启用或重新安装。
第四步:纳入团队规范
建议把技能产出的目录结构(steps/fixtures.ts、steps/parameters.ts、按领域拆分的 common/、auth/、products/)直接固化为团队约定,后续每次让 AI 生成步骤定义时都沿用同一套结构,避免风格漂移。
该技能的主要功能和特点
createBdd()类型安全步骤函数:通过解构出Given / When / Then三个函数来定义步骤,与 Playwright fixtures 和断言天然集成,参数带 TS 类型标注,写错类型在编译期就能发现。- 全量 Playwright fixtures 可直接使用:
page、context、request、browserName等 fixture 在步骤回调中直接可取,例如用context.cookies()断言 cookie 数量。 - 四种内置参数类型 + 正则匿名参数:
{string}、{int}、{float}、{word}覆盖大多数场景;需要更灵活匹配时,用/^我在搜索框中输入 "(.*)"$/这类正则捕获组即可。 - 自定义参数类型(
defineParameterType):可以把red|green|blue、true|false、日期格式等抽象成语义化参数,并在transformer里直接完成类型转换(如字符串转Date、字符串转布尔)。 - 自定义 fixtures 与「设置/清理」封装:用
base.extend()增加todoPage、apiClient、authenticatedPage等 fixture,并在use()前后分别完成登录与登出,把测试准备成本降到最低。 - Page Object Model 深度集成:页面对象类(定位器 +
goto/addTodo/expectTodoCount等方法)通过 fixture 注入步骤,步骤定义只表达业务语义,不出现裸选择器。 - 装饰器写法(
playwright-bdd/decorators):支持@Fixture、@Given、@When、@Then的类式组织,适合步骤数量多、希望按类分组的团队。 - DataTable 三种解析方式:
raw().flat()处理单列列表、hashes()处理带表头表格、rowsHash()处理「键 | 值」垂直表格,覆盖了绝大多数参数化数据场景。 - Doc Strings:多行文本直接作为字符串参数注入,
"""json开头的代码块还能JSON.parse后作为请求体发出。 - 跨步骤共享状态(World 模式):通过自定义 fixture 维护一个
world对象,承载currentUser、createdItems等中间状态,替代容易出问题的全局变量。 - 错误处理与条件跳过:既有"抛错标记待定步骤"的写法,也有基于
browserName判断后test.skip()的跨浏览器兼容处理。 - 步骤可重用性最佳实践:包括通用导航步骤(用路由映射表
routes兜底)、通用表单填充、通用点击(button 与 link 双角色兜底)三类高复用模板。
与"普通工具/普通提问"相比,它强在结构化:不是给一段能跑的代码,而是给出「fixtures → 参数类型 → 页面对象 → 步骤文件」的四层分层,以及每层之间的正确引用关系。
如何使用该技能?
步骤 1:先确认项目分层
在让 AI 生成代码前,先把目录约定好,技能的产出才能直接落位:
steps/
├── fixtures.ts # 共享 fixtures 与 createBdd(test)
├── parameters.ts # 自定义参数类型
├── common/
│ ├── navigation.steps.ts
│ └── forms.steps.ts
├── auth/
│ ├── login.steps.ts
│ └── logout.steps.ts
└── products/
├── catalog.steps.ts
└── cart.steps.ts
步骤 2:从最简单的步骤定义开始
输入示例(你的提问):
帮我用 createBdd() 写三个步骤:我在主页上、我点击登录按钮、我应该看到仪表板。
预期输出:
// steps/common.steps.ts
import { createBdd } from 'playwright-bdd';
const { Given, When, Then } = createBdd();
Given('我在主页上', async ({ page }) => {
await page.goto('/');
});
When('我点击登录按钮', async ({ page }) => {
await page.getByRole('button', { name: 'Login' }).click();
});
Then('我应该看到仪表板', async ({ page }) => {
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
});
注意输出中的定位方式统一使用 getByRole,这是可维护性的关键。
步骤 3:把登录态抽成 fixture
输入示例:
我需要一个已登录的 page fixture,测试前登录、测试后登出,其他步骤直接用它。
预期输出要点:
export const test = base.extend<{ authenticatedPage: Page }>({
authenticatedPage: async ({ page, context }, use) => {
await page.goto('/login');
// ... 填写邮箱密码并登录
await page.waitForURL('/dashboard');
await use(page);
await page.goto('/logout');
},
});
export const { Given, When, Then } = createBdd(test);
关键点:自定义了 fixtures 就必须用 createBdd(test),而不是空参数的 createBdd(),否则步骤里取不到 authenticatedPage。
步骤 4:接入 Page Object Model
输入示例:
我有 TodoPage 页面对象(含 goto、addTodo、removeTodo、toggleTodo、expectTodoCount),帮我把「添加任务/完成任务/移除任务/任务数量」写成步骤。
预期输出:
import { Given, When, Then } from './fixtures';
Given('我在任务页面上', async ({ todoPage }) => {
await todoPage.goto();
});
When('我将 {string} 添加到我的任务中', async ({ todoPage }, text: string) => {
await todoPage.addTodo(text);
});
Then('应该有 {int} 个任务', async ({ todoPage }, count: number) => {
await todoPage.expectTodoCount(count);
});
步骤文件里不再出现任何 getByPlaceholder 之类的定位器,全部收敛到页面对象内部。
步骤 5:处理数据表格与 Doc Strings
对下面这段 Gherkin:
When 我创建用户:
| name | email | role |
| Alice | alice@test.com | admin |
| Bob | bob@test.com | user |
应生成使用 table.hashes() 的步骤,得到 [{ name: 'Alice', email: '...', role: 'admin' }, ...] 后再循环填表。若表格是「键 | 值」形式,则改用 rowsHash();若是单列列表,则用 raw().flat()。
Doc String 场景则直接接收 docString: string 参数;若 Gherkin 中标注为 """json,可用 JSON.parse(docString) 后交给 request.post()。
步骤 6:用 World 在步骤之间共享状态
export const test = base.extend<{ world: World }>({
world: async ({}, use) => {
await use({ createdItems: [] });
},
});
之后在「创建项目」的步骤里 world.createdItems.push(item),在「应该看到我的项目」的步骤里遍历 world.createdItems 做断言。这样每个场景都拿到全新的 world,互不污染。
步骤 7:让 AI 做一次自查
生成完成后追加一句:
检查这些步骤是否存在重复定位器、是否有未使用的 fixture、是否所有断言都用了 Playwright 的 expect。
这一步能筛掉大量"能跑但难维护"的输出。
同类型竞品对比分析
| 方案名称 | 定位 | 核心功能 | 安装/使用门槛 | 适用场景 | 优势与不足 |
|---|---|---|---|---|---|
| playwright-bdd + 本技能(步骤定义专家知识) | 在 Playwright Test 之上叠加 Gherkin 能力 | createBdd() 类型安全步骤、fixtures 复用、POM 集成、DataTable/Doc Strings、装饰器、World 状态共享 |
需 Playwright 与 TS 基础,会 fixtures 概念即可上手;AI 辅助可显著压缩样板编写时间 | 团队已有 Playwright、希望引入业务可读的 BDD 用例;从 Cucumber 迁移 | 优势:与 Playwright 原生 fixtures/断言/报告无缝共用,参数类型系统完善;不足:需理解 createBdd(test) 与自定义 fixtures 的绑定关系,初学易写错 |
| Cucumber.js(原生) | 经典 BDD 框架,自带 runner | Gherkin 解析、World、Hooks、多语言支持 | 需自行搭建浏览器驱动层(如 Selenium/Playwright 手工封装),配置量较大 | 跨语言统一 BDD 规范、非 JS 技术栈团队 | 优势:生态成熟、规范标准;不足:浏览器自动化能力需自己拼装,缺少开箱的 fixtures 与追踪报告 |
| 纯 Playwright Test(非 BDD) | 端到端测试框架 | 测试运行器、fixtures、断言、Trace Viewer | 最低,装好依赖即可写 | 研发主导、用例由工程同学维护 | 优势:结构简单、调试体验好;不足:缺少 Gherkin 这一层业务可读语言,产品/业务方难以直接评审用例 |
| CodeceptJS 等 BDD 风格封装 | 高层语义化 API 的自动化框架 | 语义化动作 API、可配合 Gherkin | 需要学习其自有 API 体系 | 快速搭建、团队不想深入底层定位器 | 优势:上手快、语义直观;不足:脱离 Playwright 原生生态,复杂场景需回退到底层,灵活度受限 |
选择建议:如果你的团队已经或将要用 Playwright,那 playwright-bdd 路线(配合本技能)摩擦最小;如果只是想要"业务能看懂的文档",纯 Playwright Test 加规范命名也能凑合;如果是跨语言组织级 BDD 规范,Cucumber 系仍是标准答案。
该技能的典型应用场景与实际体验情况
场景一:从零搭建 BDD 步骤库的前端测试工程师
痛点:项目决定引入 BDD,特征文件写了几十条,steps/ 目录却只有一个空文件;每写一条步骤都要查一遍 createBdd 的签名和 fixture 注入方式。
使用方式:把 Gherkin 特征文件内容贴上,要求"按领域拆分生成步骤定义,公共步骤抽到 common 目录"。技能会给出 common/navigation.steps.ts、auth/login.steps.ts 等文件划分,并给出通用导航步骤的路由映射表写法。
实际体验:上手难度低,几乎不需要额外学习成本就能产出可运行代码。注意事项:技能给的是"范例级"代码,路由表、选择器、断言文本必须替换成你自己项目的真实值,不能直接提交。
场景二:QA 与业务方协作的产品团队
痛点:产品经理能读懂「我以 Alice 身份登录,然后把「买牛奶」加入任务」这种句子,但看到 page.getByPlaceholder(...) 就完全失去参与感,需求评审和用例评审是两条线。
使用方式:QA 先把 Gherkin 写到特征文件,再让技能生成对应步骤;产品只需 review .feature 文件。此后新增场景时,往往是"复用已有步骤",技能里关于步骤可重用性(通用导航、通用表单填充、通用点击)的模板正好派上用场。
实际体验:效果体现在沟通成本上——用例评审从"看代码"回到"读句子"。注意事项:通用步骤命名要克制,过度抽象(比如"我操作页面")会让特征文件失去可读性,反而违背 BDD 初衷。
场景三:从 Cucumber 迁移到 Playwright BDD 的老项目
痛点:老项目里满是 World、DataTable、Doc String 的写法,迁移时不确定哪些能一一对应。
使用方式:直接把老步骤文件贴给技能,要求"转换为 playwright-bdd 写法"。结果通常是:World → 自定义 fixture 承载的 world 对象;DataTable.raw() → table.raw().flat(),rows() 系列 → hashes() / rowsHash();多行文本 → docString: string 参数。
实际体验:迁移映射清晰,能一次性把一批步骤改完。注意事项:装饰器写法(@Fixture + @Given)属于可选风格,团队如果没约定就统一用函数式,避免两套风格并存。
场景四:需要登录态与鉴权链路复用的复杂系统
痛点:每一条用例都要先登录,重复写登录步骤让套件又慢又脆;跨浏览器的差异还要单独做条件跳过。
使用方式:让技能生成带 setup/teardown 的 authenticatedPage fixture,并在步骤内部用 browserName 判断后调用 test.skip(true, '...')。
实际体验:登录逻辑只写一次,套件执行时间明显下降,稳定性提升。注意事项:fixture 里的登出/清理逻辑要确保在 await use() 之后执行,否则异常场景下会残留会话。
该技能能为用户带来的价值
- 效率提升:步骤定义的样板代码(import、
createBdd、参数解构、类型标注)几乎全部由 AI 补齐,工程师只需替换业务值。原本一条步骤要查文档 + 试错 5~10 分钟,现在基本是"提需求 → 拿到结构 → 改值"。 - 门槛降低:BDD 落地最大的拦路虎不是 Gherkin 语法,而是"fixtures 和步骤之间怎么串"。技能把
base.extend()→createBdd(test)→ 步骤文件引用这条链路完整展示,新手不必啃文档也能照做。 - 质量与一致性:统一的参数类型(
{string}/{int}/{float}/{word})、统一的定位方式(优先getByRole/getByLabel)、统一的断言方式(Playwrightexpect),让多人协作的步骤库不会变成"风格博物馆"。 - 可维护性:Page Object Model 与 fixtures 的组合,让选择器变更有唯一改动点;
world对象让跨步骤状态有明确生命周期,避免全局变量导致的偶发失败。 - 长期价值:这是一份可复用的团队资产——技能产出的目录结构、参数类型库(如
color、boolean、date)、通用步骤模板,会随着项目积累逐步沉淀为内部测试框架规范,新成员入职可直接沿用。
常见问题 FAQ
Q1:这个技能怎么安装?装完怎么确认生效?
在技能平台搜索英文名 playwright-bdd-step-definitions 或技能ID 13923 后安装启用;若是命令行形式的安装入口,具体命令与参数以官方说明为准。验证方式:让 AI 用 createBdd() 写一条登录步骤,若输出中出现 import { createBdd } from 'playwright-bdd'、const { Given, When, Then } = createBdd(); 以及带类型的参数,说明已生效。另外注意,该技能声明为不可由用户直接调用(user-invocable: false),通常由上层流程在需要编写步骤定义时自动引用。
Q2:安装这个技能收费吗?
技能本身属于知识型技能,其定价与授权取决于你所使用的技能平台,请以官方说明为准;它指导使用的 playwright-bdd 与 Playwright 属于开源库,各自的许可协议请以官方说明为准。建议在团队落地前先确认平台侧的费用与合规要求。
Q3:它适合谁用?不做 BDD 的项目有必要装吗?
最适合三类人:正在用 playwright-bdd 写步骤定义的测试工程师;准备从 Cucumber 迁移到 Playwright BDD 的团队;需要维护大量回归用例、希望统一步骤风格的 QA 团队。如果项目只写纯 Playwright Test、不打算引入 Gherkin,那这个技能的收益有限,可以先不装。
Q4:生成出来的代码能直接跑吗?需要注意什么?
不能直接当成品用。技能提供的是结构化范例:路由地址、页面元素名称、断言文本都要替换成你项目的真实值;自定义 fixtures 时要记得把 createBdd() 改成 createBdd(test);使用自定义参数类型时要在步骤文件里 import './parameters';装饰器写法与函数式写法不要混用。
Q5:和直接用 Cucumber.js 相比,怎么选?
看你的底层自动化栈:如果已经或计划用 Playwright,选 playwright-bdd 路线,能直接复用 Playwright 的 fixtures、断言、追踪能力和测试报告,改动成本最低;如果核心诉求是跨语言、跨技术栈统一 BDD 规范和生态插件,Cucumber 系更合适,但浏览器自动化层需要自己搭建封装。简单记:以 Playwright 为中心 → 本技能路线;以 BDD 规范为中心 → Cucumber 系。