使用 Codex 修复 Bug:复现、定位、最小补丁与回归测试
高质量 Bug 修复必须完成四步:
- 能稳定复现;
- 找到根因;
- 用最小改动修复;
- 用回归测试证明不会复发。
不要一开始就让 Codex“直接修一下”。
1. 提供完整 Bug 信息
推荐模板:
问题:
用户修改昵称后页面显示“保存成功”,但刷新后恢复旧昵称。
环境:
- 分支:main
- 浏览器:Chrome
- 开发环境:本地
复现步骤:
1. 登录测试账号;
2. 打开 /settings/profile;
3. 修改昵称;
4. 点击保存;
5. 看到成功 Toast;
6. 刷新页面。
实际:
显示旧昵称。
预期:
显示新昵称。
日志:
<粘贴请求、响应或错误>
限制:
- 不改变 API 返回结构;
- 保持补丁最小;
- 添加回归测试。
2. 先复现,不要先修改
先不要修改代码。
根据复现步骤定位页面提交、API 请求、服务写入和重新加载链路。
尝试在本地复现,记录实际命令、请求和状态变化。
为什么重要:
- 可能是前端假成功;
- 可能是后端没有提交事务;
- 可能是缓存;
- 可能是请求字段被丢弃;
- 可能是读取和写入使用不同数据源;
- 可能是测试环境本身配置错误。
没有复现就修改,容易只掩盖症状。
3. 让 Codex建立故障链路
要求输出:
请给出完整故障链:
用户操作 -> 前端状态 -> 请求 Payload -> Controller -> Service -> Repository -> 数据库 -> 重新读取。
每一步引用文件和函数。
标记已经证实和仍是假设的部分。
这种结构能避免 Codex把可能性当根因。
4. 区分根因和症状
假设发现:
- 前端无论响应状态都显示成功 Toast;
- 后端 DTO 忽略了
displayName;
第一个是症状放大器,第二个可能是实际写入失败根因。一个任务可能需要修两个问题:
- 后端正确保存;
- 前端只在成功响应后提示。
但应说明每项修改对应哪个故障。
5. 要求提出最小补丁
基于已确认根因,提出最小修复方案。
不要重构无关认证或设置模块。
列出要修改的文件、行为变化和回归测试。
得到方案后再修改。
如果 Codex建议大范围重构:
把修复限制在根因相关层。架构改进作为后续建议,不放入当前补丁。
6. 添加回归测试
好的回归测试应在修复前失败,修复后通过。
先添加能够稳定重现问题的最小测试,并确认它在当前实现上失败。
然后修改生产代码,使该测试通过。
这称为 Red → Green 流程。
测试层级选择:
- 纯函数错误:单元测试;
- DTO/序列化错误:接口或 schema 测试;
- 数据库事务错误:Repository/集成测试;
- 页面流程错误:组件或 E2E 测试;
- 多层协作错误:最小跨层集成测试。
7. 日志分析 Prompt
分析以下日志,先建立时间线,不修改代码。
要求:
- 区分错误源和后续连锁错误;
- 找到第一个异常事件;
- 关联代码路径;
- 列出需要补充的日志或实验;
- 不足以确定时明确说明。
<日志>
大量日志不要只粘贴最后一行。应包含:
- 时间;
- 请求 ID;
- 线程或任务 ID;
- 调用栈;
- 配置;
- 前后事件。
8. 构建失败 Prompt
目标:修复当前分支构建失败。
命令:
pnpm build
错误:
<完整错误>
要求:
1. 先在当前环境重现;
2. 找到第一个真实编译错误;
3. 不通过关闭 TypeScript 严格模式解决;
4. 不使用 any 掩盖问题;
5. 修复后重新运行 build、typecheck 和相关测试。
9. CI 失败 Prompt
调查 CI 失败,先比较本地和 CI 环境差异。
信息:
- Workflow:.github/workflows/test.yml
- 失败 Job:unit-test
- 本地通过,CI 失败
- 日志:<内容>
检查:
- Node/Java/Python 版本;
- 时区和 Locale;
- 文件系统大小写;
- 缺失环境变量;
- 并发和测试隔离;
- 缓存污染;
- 锁文件。
10. 竞态和偶发 Bug
偶发 Bug 不能只运行一次。
该测试约 20 次失败 1 次。
先不要修改代码。
分析共享状态、异步等待、时间依赖和资源清理。
建立可重复压力运行命令,至少运行足够次数收集失败模式。
可以让 Codex编写临时重复脚本,但不要把调试脚本误提交到生产代码。
11. 修复后必须重新执行复现步骤
修复后:
1. 重新执行原始复现步骤;
2. 运行回归测试;
3. 运行最小相关测试套件;
4. 运行 Lint 和类型检查;
5. 汇报命令和结果。
如果原始问题无法自动复现,应给出明确手工复验步骤。
12. 使用 /review 检查补丁
/review
关注点:
重点检查:
- 补丁是否只修复症状;
- 是否改变成功/失败语义;
- 是否引入兼容性问题;
- 回归测试是否真正覆盖旧问题;
- 是否遗漏错误分支。
13. 一个后端 Bug 示例
问题:重复回调导致订单重复记账。
Prompt:
问题:支付回调偶尔使订单入账两次。
先调查:
- 回调入口;
- 签名验证;
- 幂等键;
- 事务边界;
- 订单状态更新;
- 重试机制。
要求:
- 构造并发或重复回调测试;
- 在当前实现上证明失败;
- 修复必须在服务端保证幂等;
- 不依赖前端避免重复请求;
- 说明数据库约束和事务是否足够。
此类问题不能只加内存锁,因为多实例部署下无效。
14. 一个 Flutter Bug 示例
问题:列表快速返回后偶尔出现 setState() called after dispose()。
复现:
1. 打开订单页;
2. 立即下拉刷新;
3. 请求未完成时返回;
4. 偶发报错。
要求:
- 找到异步回调和 Widget 生命周期关系;
- 使用项目现有状态管理方式修复;
- 不只是全局吞掉异常;
- 添加可行的 Widget 测试;
- 运行 flutter analyze 和相关测试。
15. 常见错误
让 Codex猜根因
应要求复现、证据和实验。
修改太多文件
Bug 修复应优先最小补丁。重构另开任务。
测试在修复前就通过
说明测试没有覆盖 Bug,需重新设计。
只运行新测试
还要运行受影响模块的已有测试。
修改测试以适配错误行为
除非需求变化,否则不要通过降低断言让测试通过。
16. Bug 修复报告模板
## Root cause
- 根因:
- 证据:
- 为什么之前未发现:
## Fix
- 修改:
- 为什么是最小方案:
## Regression test
- 修复前结果:
- 修复后结果:
## Verification
- 命令:
- 结果:
## Risk
- 未覆盖环境:
- 后续建议:
官方参考
- https://learn.chatgpt.com/docs/prompting
- https://learn.chatgpt.com/guides/best-practices
- https://learn.chatgpt.com/docs/code-review
- https://learn.chatgpt.com/docs/codex/cli
资料核对日期:2026-07-14。