痛点:回归测试越堆越多,手敲命令成体力活
测试同学每天面对的场景很熟悉:打开页面、截图、点击、填表单、验证结果——每个操作都对应一条 playwright-cli 命令。单个用例还好,一旦回归任务堆积,手敲命令就成了体力活,还容易出错。
核心问题在于:Agent(Codex)缺少一份操作手册。它不知道什么时候该用 open、什么时候该 snapshot、Ref 编号从哪份快照文件读、什么时候该开有头模式。
Skill 就是这份手册。 安装之后,用自然语言描述测试目标,Codex 按 SKILL.md 里的流程编排 CLI 命令,不再需要手写命令,也无需配置 MCP JSON。
整体思路:从"敲命令"到"说目标"
| 维度 | 之前(纯 CLI) | 之后(Skill) |
|---|---|---|
| 操作方式 | 手敲每条命令 | 自然语言描述测试目标 |
| 知识沉淀 | 命令存在个人记忆里 | Skill 作为团队可复用资产 |
| 维护成本 | 每个用例独立维护 | 复用同一套 SKILL.md |
| 产出物 | 散落的截图和日志 | PO 分层脚本 + 可追溯执行证据 |
第一步:环境准备——把 Codex 和 Playwright 装好
1. 确认基础工具就绪
# 检查 npx 是否可用(Skill 的 wrapper 脚本依赖它)
command -v npx >/dev/null 2>&1
如果 npx 不可用,先装 Node.js/npm:
npm install -g @playwright/mcp@latest
playwright-cli --help
2. 把 Playwright Skill 放到 Codex 的 skills 目录
Codex 的全局 Skill 放在 ~/.codex/skills/(Windows 对应 C:\Users\<用户名>\.codex\skills\):
# 克隆或下载 playwright-skill 目录
cp -r playwright-skill ~/.codex/skills/
# 重启 Codex 或新开会话,Skill 就生效了
3. 设置环境变量(可选,方便后续调用)
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
export PWCLI="$CODEX_HOME/skills/playwright/scripts/playwright_cli.sh"
第二步:理解 Skill 的"隐式触发"
很多团队卡在这一步:Skill 装好了,但不知道怎么用。
Codex 的 Skill 分两种调用方式:
- 隐式调用:只要任务描述落在适用范围内,模型自动判断读取并执行,无需显式点名
- 显式调用:需要用户主动点名
$xxx来触发
这个 Playwright Skill 属于隐式调用——正常描述测试需求即可,模型会根据 SKILL.md 的 description 自动匹配。
比如直接说:
帮我测试 Sauce Demo 的登录功能,用 standard_user 账号登录,
验证能成功进入商品列表页。
Codex 会自动识别这是 Playwright Skill 的职责范围,然后触发执行。
第三步:核心工作流——snapshot 驱动的 CLI 交互
有了 Skill,Codex 执行 UI 自动化的核心流程可以用四步循环概括:
1. open → 打开页面
2. snapshot → 获取当前页面 DOM 的结构化快照(每个可交互元素分配 Ref 编号)
3. 操作 → 用 Ref 编号点击/填写(click e15 / fill e1 "用户名")
4. 重新 snapshot → 页面导航或 DOM 变化后再次获取新 Ref
关键原则
每一次交互都基于最新快照里的 Ref 编号,而不是硬编码的 CSS 选择器或 XPath。页面轻微改动后只需重新 snapshot,不用重写脚本。
当命令因为找不到某个 Ref 而失败时,等待动态内容稳定后重新 snapshot 即可。
第四步:实战跑通——Sauce Demo 完整购买流程
用自然语言给 Codex 下达这样的任务:
用 Playwright Skill 完成 Sauce Demo 的完整购买流程:
用 standard_user 登录,把 Sauce Labs Backpack 加入购物车,
进入购物车确认商品,填写结账信息(名字、姓氏、邮编),
完成结算,最后截图验证订单成功页面。
Codex 收到任务后,会按 Skill 编排成以下操作序列:
登录阶段:
1. open https://www.saucedemo.com --headed — 启动浏览器
2. snapshot — 获取登录页元素 Ref
3. fill e1 "standard_user" — 用户名
4. fill e2 "secret_sauce" — 密码
5. click e3 — 登录按钮
6. snapshot — 确认进入商品列表页
加购阶段:
7. 从最新快照找到"Add to cart"按钮 Ref
8. click → snapshot — 验证购物车角标变为 1
9. 点击购物车图标 → snapshot — 确认商品在列表
结算阶段:
10. click Checkout → snapshot → 填写 First Name / Last Name / Zip
11. click Continue → snapshot → 验证价格计算正确
12. click Finish → snapshot → 截取订单成功页面
为什么要反复 snapshot?每次页面导航或 DOM 大幅变化后,之前的 Ref 编号就失效了——登录前的 Ref 指向登录页元素,登录后商品列表页的 DOM 完全不同,必须重新获取。
第五步:结果沉淀——把执行记录变成 PO 分层脚本
跑通流程只是第一步,可复用的测试资产才是长期价值。
Skill 执行完成后,可以把整个操作记录和快照数据转化为 PO(Page Object)分层脚本:
sauce-demo-tests/
├── tests/ # 测试用例
├── pages/ # Page Object 类(LoginPage、InventoryPage、CheckoutPage)
├── components/ # 共享 UI 组件(Cart 等)
├── data/ # 测试数据
└── helpers/ # 可复用函数
从 Skill 的执行记录里可以提取三样东西:
| 提取内容 | 对应产物 |
|---|---|
| 操作序列(open → fill → click → snapshot) | 测试脚本里的 page.goto() / page.fill() / page.click() |
| 快照里的 Ref 元素定位信息 | 稳定的 CSS 选择器,反查生成 data-test="username" 这类属性 |
| 每一步的快照"成功状态" | 断言条件,如 expect(page).toHaveURL(/\/checkout-step-2/) |
为什么推荐这种方式而非 MCP?
| 方案 | 适用场景 |
|---|---|
| MCP | 探索阶段、需要精细控制工具调用、临时一次性测试 |
| Skill + CLI | 正式测试项目、需要团队协作和长期维护、追求可复用资产 |
测试项目建议默认使用 Skill 方案:把 Playwright 封装成 Skill 后,换测试站点只需修改 URL 和部分定位逻辑,框架整体不用动。
常见问题
Q:Skill 装完不知道怎么触发怎么办? A:在对话里直接描述你的测试目标,不用记特殊命令。如果不确定是否生效,可以问"Codex,你现在有哪些可用的 Skill?"
Q:Ref 编号会过期吗? A:会的。每次页面跳转或 DOM 大幅变化后,需要重新 snapshot 获取新 Ref。这是正常行为,不是 bug。
Q:能不能不用 Skill,直接用 playwright-cli? A:可以,但那样你需要每次都手写完整命令序列,无法享受"自然语言描述 → 自动编排"的收益。
Q:Team 共享怎么办?
A:将 Skill 目录打包,团队成员各自复制到 ~/.codex/skills/,或统一维护到一个共享位置后 symlink 过去。
写在最后
Skill 的价值不只是把"敲命令"变成"说话",而是把测试流程从手工驱动的执行变成描述驱动的编排。CLI 命令仍然是底层引擎,但 Skill 给了它一份操作手册,让 Codex 知道什么时候该用什么命令、拿哪份快照、怎么验证结果。
选一个你每周都要做的重复性 UI 测试任务,尝试把它封装成 Skill。一周后你会发现工作效率有了质的飞跃。
来源:AI 湿《把 Playwright 封装成测试 Skill》,来源 Wmrh.cn,2026-08-18 发布,经本教程改写与结构化。
资料最后核对日期:2026-09-02 · 内容整理自 CodexGuide 社区公开教程