AI 学习指南
课程章节
本文目录
开发工作流11

使用 Codex 修复 Bug:复现、定位、最小补丁与回归测试

建立可重复的 Codex 调试流程,避免猜测式修复,并通过证据和回归测试确认根因。

进阶 20 分钟 17 2026-07-14 更新

使用 Codex 修复 Bug:复现、定位、最小补丁与回归测试

高质量 Bug 修复必须完成四步:

  1. 能稳定复现;
  2. 找到根因;
  3. 用最小改动修复;
  4. 用回归测试证明不会复发。

不要一开始就让 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

第一个是症状放大器,第二个可能是实际写入失败根因。一个任务可能需要修两个问题:

  1. 后端正确保存;
  2. 前端只在成功响应后提示。

但应说明每项修改对应哪个故障。

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
- 未覆盖环境:
- 后续建议:

官方参考

资料核对日期:2026-07-14。

继续学习

$ start project✓ context loaded✓ task complete

claude-code

入门

Claude Code 从入门到实战

基于 Anthropic 官方文档,从安装、项目上下文和权限配置,到调试、测试与交付的完整入门课程。

78 分钟开始学习
$ start project✓ context loaded✓ task complete

cursor

开发

Cursor AI 开发指南

深入介绍 Cursor 的智能补全、Agent、规则配置和代码库理解能力。

36 分钟开始学习