[测试工具] 用 Codex 做测试实战:从需求分析到自动化用例落地
原创内容,未获授权禁止转载、转发、抄袭。
这段时间我一直在尝试把 Codex 放到测试工作流里,不是让它“替我测试”,而是让它帮我处理那些重复、耗时间、但又不能完全省掉的工作。
比如:
- 看需求后整理测试点
- 读代码找影响范围
- 根据已有页面写 Playwright 脚本
- 分析自动化失败原因
- 把团队里的测试规范沉淀成 skill
用下来最大的感受是:Codex 更像一个测试开发搭子,而不是一个万能测试机器人。
你给它一个模糊任务,它也会写得很虚;
你给它上下文、边界和检查标准,它就能帮你省不少时间。
这篇就用一个实际测试场景,讲一下我是怎么用 Codex 做测试的。
一、场景背景:优惠券领取功能
为了方便说明,这里用一个脱敏后的例子。
需求大概是这样:
用户进入活动页后,可以领取一张优惠券。 每个用户只能领取一次。 优惠券有活动时间、库存数量、使用门槛。
如果用户未登录、活动未开始、活动已结束、库存不足、重复领取,都需要给出对应提示。
这个功能看起来不复杂,但测试点其实不少。
如果按传统方式,我一般会先写测试点,然后补接口场景,再考虑自动化脚本。
现在我会先让 Codex 做第一轮拆解。
二、第一步:让 Codex 先读需求,不要急着写用例
我比较不建议一上来就问:
帮我写测试用例
这样出来的内容通常很通用,看起来整齐,但不一定贴业务。
我更喜欢这样问:
你先不要写测试用例。
请站在资深测试工程师视角,阅读下面需求,帮我做三件事:
1. 列出这个功能的核心业务规则
2. 找出最容易出问题的风险点
3. 按主流程、异常流程、边界场景、数据一致性、安全风险进行分类
要求:
- 不要输出太空泛的内容
- 每个风险点都要说明为什么需要测
- 如果需求描述不完整,请列出需要追问产品的问题
需求如下:
这样问的好处是,它不会急着堆用例,而是先帮你把业务规则捋出来。
对于优惠券领取场景,我比较关注这些点:
- 用户是否登录
- 活动是否在有效时间内
- 库存是否足够
- 是否重复领取
- 同一用户多端同时点击是否会重复领取
- 领取成功后库存是否正确扣减
- 领取成功后用户券包是否能查询到
- 接口重复请求是否幂等
- 前端按钮置灰是否只是前端限制,后端是否也校验
这里面最关键的是:不要只测页面提示,要测数据状态。
三、第二步:让 Codex 帮我读代码找影响范围
如果项目代码在本地,我会让 Codex 先读代码。
提示词一般这样写:
请你先阅读当前项目中和“优惠券领取”相关的代码,不要改代码。
重点帮我找:
1. 前端页面入口
2. 领取按钮的交互逻辑
3. 调用的接口地址
4. 接口返回码和错误提示处理
5. 是否存在防重复提交逻辑
6. 是否有现成的测试用例或自动化脚本
最后输出:
- 涉及文件列表
- 主要调用链路
- 你认为测试时最需要关注的风险点
这一步很实用。
以前我可能要自己搜关键词,比如 coupon、receive、activity、voucher。
现在可以让 Codex 先扫一遍,给出一个影响范围。
但这里一定要注意:Codex 给出的文件列表要自己再确认。
我一般会让它输出文件路径,然后自己点进去看一眼。
不要它说哪个文件有关,你就完全相信。
四、第三步:生成测试点,但要带上检查标准
当业务规则和代码影响范围清楚后,再让它生成测试点。
提示词可以这样写:
基于上面的需求和代码影响范围,请帮我生成测试点。
要求:
1. 不要写成长篇大论
2. 按模块分类
3. 每个测试点包含:场景、操作、预期结果、验证方式
4. 验证方式要区分:页面验证、接口验证、数据库/数据状态验证
5. 重点补充并发、重复请求、库存扣减、用户券包一致性场景
输出为 Markdown 表格。
我比较喜欢让它多加一列“验证方式”。
因为很多测试点如果只写“页面提示正确”,其实是不够的。
比如:
| 场景 | 操作 | 预期结果 | 验证方式 |
|---|---|---|---|
| 正常领取 | 登录用户点击领取 | 提示领取成功 | 页面提示 + 查询用户券包 |
| 重复领取 | 已领取用户再次点击 | 提示已领取 | 页面提示 + 接口返回码 |
| 库存不足 | 库存为 0 时点击领取 | 提示已领完 | 页面提示 + 库存不变 |
| 并发领取 | 同一用户多端同时领取 | 只能成功一次 | 接口响应 + 用户券包数量 |
| 活动未开始 | 活动开始前点击 | 提示活动未开始 | 页面提示 + 接口校验 |
| 活动已结束 | 活动结束后点击 | 提示活动已结束 | 页面提示 + 接口校验 |
这里 Codex 能帮我们快速出初稿,但测试人员要继续补业务经验。
比如优惠券场景,我一定会补两个点:
- 重复点击领取按钮,前端是否禁用按钮
- 绕过前端直接调接口,后端是否仍然防重复领取
这两个点经常能测出问题。
五、第四步:让 Codex 生成 Playwright 脚本初稿
测试点确认后,可以让 Codex 写自动化脚本。
这里不要简单说“写自动化脚本”。
最好告诉它项目用什么框架、怎么定位、哪些数据从环境变量读取。
我的提示词一般是:
请根据下面测试点生成 Playwright 自动化脚本。
项目约束:
1. 使用 @playwright/test
2. 优先使用 getByRole、getByText、getByTestId
3. 不要使用 XPath
4. 测试环境地址从 TEST_BASE_URL 读取
5. 登录账号从 TEST_USERNAME、TEST_PASSWORD 读取
6. 不要写死真实域名、真实账号、真实 token
7. 领取成功后,需要调用接口查询用户券包做二次断言
8. 代码要拆成:登录、进入活动页、领取优惠券、查询券包几个方法
测试点:
它可能会生成类似这样的脚本:
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();
await expect(page.getByText('首页')).toBeVisible();
}
async function openActivityPage(page) {
await page.goto(`${baseUrl}/activity/coupon`);
await expect(page.getByText('优惠券领取')).toBeVisible();
}
async function receiveCoupon(page) {
await page.getByRole('button', { name: '立即领取' }).click();
}
test('用户成功领取优惠券后,券包中可以查询到该券', async ({ page, request }) => {
await login(page);
await openActivityPage(page);
await receiveCoupon(page);
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();
});
这类代码不能直接无脑提交,但已经可以省下不少起步时间。
我一般会继续让 Codex 做一次自查。
请你 review 上面的 Playwright 脚本,重点检查:
1. 是否存在不稳定定位
2. 是否依赖脏数据
3. 是否缺少等待或断言
4. 是否有账号、域名、token 等敏感信息
5. 是否适合接入 CI 执行
请直接指出问题,并给出修改建议。
这个步骤很有必要。
Codex 写完代码后,再让它站在 code review 视角看一遍,通常能发现一些低级问题。
六、第五步:失败后让 Codex 帮忙看日志
自动化跑起来以后,失败是常态。
以前看到失败日志,我一般要自己看截图、看 trace、看接口返回。
现在可以把关键信息整理给 Codex。
提示词:
你是一名测试开发,请分析下面 Playwright 自动化失败原因。
请输出:
1. 失败现象
2. 最可能原因
3. 是脚本问题、环境问题,还是产品缺陷
4. 需要进一步确认的信息
5. 建议修复方案
测试日志:
接口返回:
截图描述:
比如失败日志里有:
expect(locator).toBeVisible() failed
Locator: getByText('领取成功')
Timeout: 30000ms
接口返回:{"code":"COUPON_STOCK_EMPTY","message":"优惠券已领完"}
Codex 基本会判断出:
- 脚本期望领取成功
- 但接口实际返回库存不足
- 可能是测试数据没有初始化库存
- 优先检查造数逻辑,而不是直接怀疑前端页面
这类分析虽然不一定百分百正确,但能帮你快速缩小范围。
七、把测试经验沉淀成 skill
我觉得 Codex 真正好用的地方,不只是单次问答,而是可以把团队习惯沉淀下来。
比如我们希望每次写测试用例都遵守这些规则:
- 必须覆盖主流程、异常流程、边界值
- 接口类功能必须考虑幂等性
- 涉及金额、库存、优惠券必须验证数据一致性
- 自动化脚本不能写死账号、域名、token
- Playwright 优先使用稳定定位方式
- 输出结果要适合测试人员直接评审
这时可以写一个 skill。
示例:SKILL.md
---
name: test-case-and-playwright
description: 当需要根据需求生成测试点、测试用例或 Playwright 自动化脚本时使用。
---
# 测试用例与 Playwright 自动化规范
## 测试点生成规则
生成测试点时必须覆盖:
1. 主流程
2. 异常流程
3. 边界值
4. 权限校验
5. 幂等性
6. 数据一致性
7. 异常恢复
涉及以下业务时要重点补充:
- 订单:重复提交、状态流转、金额一致性
- 优惠券:重复领取、库存扣减、用户券包一致性
- 支付:支付失败、回调重复、金额校验
- 权限:越权访问、资源归属校验
## Playwright 脚本规则
生成脚本时必须遵守:
1. 使用 @playwright/test
2. 优先使用 getByRole、getByText、getByTestId
3. 不使用 XPath
4. 环境地址从 TEST_BASE_URL 读取
5. 账号密码从环境变量读取
6. 不写死 token、cookie、真实域名
7. 核心业务场景必须补接口或数据断言
8. 重复动作要封装成方法
## 输出格式
如果生成测试点,使用 Markdown 表格。
如果生成脚本,输出完整代码,并在最后列出:
- 依赖的测试数据
- 需要配置的环境变量
- 可能不稳定的地方
有了这个 skill 后,后面每次让 Codex 写测试点或脚本,就不用反复交代这些规则。
这比单纯收藏一堆提示词更实用。
八、我现在比较推荐的 Codex 测试工作流
目前我自己比较顺手的流程是:
这里面最关键的是两次人工介入:
第一次是在测试点阶段,补业务风险。
第二次是在脚本阶段,补数据准备和断言。
如果这两步省掉,Codex 很容易生成一堆“看起来能用,但长期维护很痛”的东西。
九、几个真实踩坑
1. 不要让 Codex 直接编接口
如果你没有给它接口文档或代码上下文,它可能会自己猜接口路径。
比如它可能写出:
/api/coupon/receive
/api/user/coupons
看起来很合理,但项目里不一定真有。
所以一定要让它先读代码,或者把接口文档贴进去。
2. 不要让它直接写真实账号密码
提示词里要明确说:
账号、密码、token、cookie、域名都必须从环境变量读取,不允许写死。
这个习惯很重要。
3. 不要只让它断言页面文案
很多 AI 生成的 UI 自动化脚本,只会写:
await expect(page.getByText('领取成功')).toBeVisible();
这不够。
优惠券领取这种场景,至少要补:
- 用户券包是否新增
- 库存是否扣减
- 重复领取是否失败
- 接口返回码是否符合预期
4. 不要一次丢太大任务
“帮我把整个优惠券模块测试完”这种任务太大。
更好的拆法是:
先分析需求和风险点,不写用例
基于风险点生成测试点,不写脚本
基于这 3 条核心用例生成 Playwright 脚本
review 这个脚本是否稳定
任务拆小,效果会明显好很多。
十、总结
Codex 用在测试里,最有价值的地方不是“自动生成一切”,而是帮测试人员把工作流串起来。
我的建议是:
- 先让 Codex 分析需求,不要急着写用例
- 用 Codex 读代码找影响范围,但结果要人工确认
- 生成测试点时,一定要求输出验证方式
- 自动化脚本要明确环境变量、定位方式和断言要求
- 执行失败后,可以让 Codex 帮忙做日志归因
- 把团队测试规范沉淀成 skill,减少重复提示词
一句话总结:
Codex 不是替你做测试决策的人,而是帮你把测试过程里的重复劳动先跑一遍。
测试人员真正要做的,还是判断风险、确认边界、设计验证方式。
这些能力,暂时还不能交给工具。
更多推荐




所有评论(0)