原创内容,未获授权禁止转载、转发、抄袭。
最近用 Codex 做测试相关工作,我发现一个很真实的问题:
每次让它写测试用例,前 3 轮基本都在纠偏。
比如我会反复提醒它:
- 别只写主流程
- 别忘了异常场景和边界值
- 接口要考虑幂等性
- 优惠券要看库存扣减和券包一致性
- Playwright 脚本不要写死账号、域名、token
- 不要用 XPath,优先用
getByRole、getByText、getByTestId
提醒一次还好,天天提醒就很烦。
后来我想明白了:
不是 Codex 不会,而是我没有把团队测试规范喂给它。
提示词只能解决一次问题,Skill 才能沉淀长期习惯。
这篇就记录一下,我是怎么把测试用例和 Playwright 自动化规范整理成一个 Codex Skill 的。
一、为什么只靠提示词不够
一开始我也只是收藏了一堆提示词。
比如:
text
你是一名资深测试工程师,请根据需求生成测试点。
要求覆盖主流程、异常流程、边界值、权限校验、幂等性、数据一致性。
或者:
text
请根据测试用例生成 Playwright 脚本。
要求使用 @playwright/test,不要使用 XPath,不要写死账号和域名。
这些提示词当然有用,但问题也很明显:
- 每次都要复制粘贴
- 不同人写出来的提示词标准不一致
- 时间久了容易漏掉关键要求
- Codex 不知道这是团队长期规范,只会当成一次性要求
Skill 的价值就在这里:
把反复说的话,变成 Codex 自动会遵守的规则。
二、什么内容适合做成 Skill
不是所有东西都适合写进 Skill。
我自己的判断标准是:只要你反复说了 3 次以上,就可以考虑沉淀。
测试团队里比较适合做 Skill 的内容有:
| 类型 | 示例 |
|---|---|
| 测试用例规范 | 主流程、异常、边界、权限、幂等性、数据一致性 |
| 自动化脚本规范 | Playwright 定位方式、环境变量、断言要求 |
| 接口测试规范 | 请求构造、签名、鉴权、错误码、幂等 |
| 安全测试规范 | 越权、重放、敏感信息、参数篡改 |
| 缺陷分析规范 | 日志分析、截图分析、失败归因、风险等级 |
| 团队业务经验 | 订单、支付、优惠券、库存、会员等业务规则 |
不建议把太泛的东西写进去。
比如:
text
回答要专业。
代码要优雅。
测试要全面。
这种话看着正确,但对实际输出帮助不大。
Skill 里要写具体规则,比如:
text
涉及优惠券时,必须检查重复领取、库存扣减、用户券包一致性。
这才有用。
三、Skill 放在哪里,怎么生效
一个 Skill 最简单只需要一个目录和一个 SKILL.md 文件。
示例:
text
test-case-and-playwright/
└── SKILL.md
如果是 Windows,可以放在类似这样的目录:
text
C:\Users\你的用户名\.codex\skills\test-case-and-playwright\SKILL.md
如果是 Mac 或 Linux,可以放在:
text
~/.codex/skills/test-case-and-playwright/SKILL.md
创建完成后,重新打开 Codex 或开启新会话,让 Codex 重新加载技能列表。
SKILL.md 最重要的是开头的元信息:
markdown
---
name: test-case-and-playwright
description: 根据需求生成测试点、测试用例或 Playwright 自动化脚本时使用。
---
这里有个小细节:
description 要写清楚什么时候触发这个 Skill。
因为 Codex 判断要不要使用 Skill,主要就是看这个描述。
如果描述太模糊,它可能不会触发。
不要写:
markdown
description: 帮助测试工作。
更建议写:
markdown
description: 根据需求、PRD、接口文档或代码变更生成测试点、测试用例、测试数据设计、Playwright 自动化脚本时使用。适用于功能测试、接口测试、Web UI 自动化、优惠券、订单、支付、权限等业务测试场景。
四、最小可用版 Skill
先不要一上来写得特别大。
可以从一个最小可用版开始。
markdown
---
name: test-case-and-playwright
description: 根据需求、PRD、接口文档或代码变更生成测试点、测试用例、测试数据设计、Playwright 自动化脚本时使用。适用于功能测试、接口测试、Web UI 自动化、优惠券、订单、支付、权限等业务测试场景。
---
# 测试用例与 Playwright 自动化规范
## 测试点生成规则
生成测试点时,必须覆盖以下维度:
1. 主流程
2. 异常流程
3. 边界值
4. 权限校验
5. 幂等性
6. 数据一致性
7. 异常恢复
输出测试点时,优先使用 Markdown 表格。
表格字段建议包含:
- 模块
- 场景
- 操作
- 预期结果
- 验证方式
- 优先级
## Playwright 脚本规则
生成 Playwright 脚本时必须遵守:
1. 使用 `@playwright/test`
2. 优先使用 `getByRole`、`getByText`、`getByTestId`
3. 不使用 XPath,除非用户明确要求
4. 测试环境地址从 `TEST_BASE_URL` 读取
5. 账号密码从环境变量读取
6. 不写死真实域名、真实账号、token、cookie
7. 核心业务场景必须补接口断言或数据断言
8. 不要只断言页面文案,要验证业务结果
这一版已经能覆盖大部分测试点生成和 Playwright 脚本生成场景。
先让它跑起来,比一开始追求完美更重要。
五、再补充业务专项规则
等最小版用顺了,再加业务专项规则。
比如优惠券、订单、权限这些场景,测试风险很固定,就适合写进去。
markdown
## 业务专项规则
涉及优惠券时,必须重点关注:
- 是否允许重复领取
- 库存是否正确扣减
- 用户券包是否能查询到
- 活动未开始、活动已结束的处理
- 库存不足时是否仍然发券
- 绕过前端直接请求接口是否能成功
- 多端同时领取是否只成功一次
涉及订单时,必须重点关注:
- 重复提交
- 金额计算
- 优惠抵扣
- 库存扣减
- 订单状态流转
- 支付失败后的恢复
- 取消订单后的库存回滚
涉及权限时,必须重点关注:
- 水平越权
- 垂直越权
- 资源归属校验
- 修改请求参数后的访问结果
- 前端隐藏按钮不等于后端已鉴权
这部分是 Skill 最有价值的地方。
因为它不是通用测试知识,而是团队长期踩坑后的经验。
六、用一个场景验证效果
比如还是优惠券领取需求:
text
用户进入活动页后,可以领取一张优惠券。
每个用户只能领取一次。
优惠券有活动时间、库存数量、使用门槛。
未登录、活动未开始、活动已结束、库存不足、重复领取,都需要给出对应提示。
没有 Skill 时,Codex 可能会输出:
| 场景 | 预期 |
|---|---|
| 用户正常领取 | 领取成功 |
| 用户重复领取 | 提示已领取 |
| 库存不足 | 提示已领完 |
| 未登录领取 | 跳转登录 |
这不能说错,但偏普通。
加了 Skill 后,我更希望它输出这种:
| 场景 | 操作 | 预期结果 | 验证方式 | 优先级 |
|---|---|---|---|---|
| 正常领取 | 登录用户点击领取 | 页面提示领取成功 | 页面提示 + 查询用户券包 | P0 |
| 重复领取 | 已领取用户再次点击 | 提示已领取 | 接口返回码 + 券包数量不变 | P0 |
| 库存不足 | 库存为 0 时领取 | 提示已领完 | 库存不变 + 未新增用户券 | P0 |
| 活动未开始 | 活动开始前领取 | 提示活动未开始 | 页面提示 + 接口返回码 | P1 |
| 活动已结束 | 活动结束后领取 | 提示活动已结束 | 页面提示 + 接口返回码 | P1 |
| 绕过前端请求 | 直接调用领取接口 | 后端仍然拦截非法请求 | 接口校验 | P0 |
| 并发领取 | 同一用户多端同时领取 | 只能成功一次 | 接口响应 + 券包数量 | P0 |
判断 Skill 是否有效,不是看输出更长了,而是看它有没有稳定补出你最关心的风险点。
比如这里我最关心的是:
- 验证方式
- 接口断言
- 数据状态
- 并发场景
- 绕过前端
- 优先级
这些内容能稳定出现,Skill 就有价值。
七、再让它生成 Playwright 脚本
有了 Skill 后,可以直接让 Codex 生成脚本:
text
基于上面的优惠券领取需求,生成一条 Playwright 自动化用例:
用户成功领取优惠券后,券包中可以查询到该券。
理想输出应该接近这样:
javascript
import { test, expect } from '@playwright/test';
const baseUrl = process.env.TEST_BASE_URL;
const username = process.env.TEST_USERNAME;
const password = process.env.TEST_PASSWORD;
async function login(page) {
await page.goto(`${baseUrl}/login`);
await page.getByRole('textbox', { name: '账号' }).fill(username);
await page.getByRole('textbox', { name: '密码' }).fill(password);
await page.getByRole('button', { name: '登录' }).click();
}
test('用户成功领取优惠券后,券包中可以查询到该券', async ({ page, request }) => {
await login(page);
await page.goto(`${baseUrl}/activity/coupon`);
await page.getByRole('button', { name: '立即领取' }).click();
await expect(page.getByText('领取成功')).toBeVisible();
const response = await request.get(`${baseUrl}/api/user/coupons`);
expect(response.status()).toBe(200);
const data = await response.json();
expect(data.list.some(item => item.couponName === '活动优惠券')).toBeTruthy();
});
注意这里有几个点:
- 没有写死真实环境
- 账号密码来自环境变量
- 没用 XPath
- 不只断言页面提示
- 补了券包接口校验
这就比单纯生成一段 UI 点击脚本靠谱很多。
八、什么时候不适合写 Skill
不是所有提示词都要沉淀成 Skill。
我一般遇到下面几种情况,不会急着写:
- 只用一次的临时任务
- 规则还没验证过,自己也没想清楚
- 强依赖某个项目的临时接口或临时页面
- 内容太业务私有,容易把敏感信息写进去
- 需求变化很快,写进去反而容易误导 Codex
我的习惯是:
先用提示词跑 2-3 次,确认这套规则确实高频、稳定、可复用,再沉淀成 Skill。
这样写出来的 Skill 才不会变成垃圾规则仓库。
九、Skill 不要写太满
Skill 不是团队测试规范文档,不需要把所有细节都塞进去。
我踩过一个坑:
一开始想把接口测试、安全测试、性能测试、用例设计、自动化规范全写到一个 Skill 里。
结果反而不好用。
原因很简单:规则太多,重点就不明显了。
我现在更建议按场景拆:
text
test-case-and-playwright
api-test-design
security-test-checklist
performance-test-analysis
defect-analysis
每个 Skill 只解决一类问题。
比如:
- 写 UI 自动化,就触发 Playwright Skill
- 写接口测试,就触发 API 测试 Skill
- 做越权测试,就触发安全测试 Skill
- 分析失败日志,就触发缺陷分析 Skill
这样会更清晰。
十、几个常见坑
1. description 写得太虚
不要写:
text
帮助测试工作。
应该写:
text
根据需求、PRD、接口文档或代码变更生成测试点、测试用例、测试数据设计、Playwright 自动化脚本时使用。
description 越清楚,越容易触发。
2. 规则写成口号
不要写:
text
测试要全面。
应该写:
text
涉及优惠券时,必须检查重复领取、库存扣减、用户券包一致性。
规则越具体,输出越稳定。
3. 把所有知识都塞进一个 Skill
Skill 太大以后,Codex 也会抓不住重点。
建议按任务拆分,而不是按部门写一个"大而全"的测试 Skill。
4. 没有验证输出效果
写完 Skill 后,一定要拿真实需求试一下。
重点看:
- 有没有按要求补风险点
- 有没有输出验证方式
- 有没有乱编接口
- 有没有写死敏感信息
- Playwright 脚本是否可维护
如果输出还是不稳定,就回去改 Skill。
5. 忘记脱敏规则
测试场景经常涉及账号、接口、token、cookie、订单号。
Skill 里最好明确写:
text
不要输出真实账号、真实 token、真实 cookie、真实生产域名。
这个习惯很重要。
十一、我建议团队怎么落地
如果是个人使用,可以先写一个 test-case-and-playwright Skill。
如果是团队使用,我建议按这个顺序推进:
- 先整理团队里最常用的测试规则
- 选一个高频场景,比如测试点生成或 Playwright 脚本
- 写一个小而清晰的 Skill
- 拿 3 个真实需求验证效果
- 根据输出问题调整规则
- 稳定后再拆分接口测试、安全测试、缺陷分析 Skill
不要一开始就追求完美。
Skill 最适合边用边改。
总结
Codex Skill 的价值,不是让 Codex 变聪明,而是让它更懂你的团队习惯。
提示词解决的是一次任务。
Skill 解决的是长期重复任务。
对测试团队来说,Skill 最适合沉淀这些东西:
- 用例设计习惯
- 业务风险清单
- 自动化脚本规范
- 接口断言要求
- 安全测试检查点
- 日志分析方法
一句话总结:
提示词是临时口头交代,Skill 是团队测试经验的工程化沉淀。
好的 Skill,不是把规则写得很多,而是把最容易遗漏、最影响质量的经验写进去。
这样 Codex 生成的内容,才更接近一个测试人员真正能用的初稿。