实战 A2:Codex 日常开发工作流——TDD、Bug 修复、重构的完整链路

实战教程系列 系列 A:A1 配置实战 | A2 日常开发 ← 本文 | A3 审查与质量 | A4 自动化 CI/CD | A5 大型项目


# Codex 日常开发工作流 ## TDD 驱动开发 - 先写测试描述 - Codex 生成测试 + 实现 - 红-绿-重构循环 ## Bug 追踪修复 - 提供复现步骤 - Codex 定位根因 - 修复 + 回归测试 ## 安全重构 - /plan 先规划 - 分步骤执行 - 每步验证

日常开发中,Codex 的价值不在于"帮你写一行代码",而在于"帮你完成一个完整的开发闭环"——从理解需求到提交代码,中间的所有步骤都可以在 Codex 的协助下高效完成。本文通过三个高频场景的完整案例,展示 Codex 在日常开发中的正确打开方式。


案例 1:TDD 驱动开发——先测试、后实现、再重构

场景:你要为电商系统实现一个折扣计算模块。需求:满 100 减 10,满 200 减 30,满 500 打 8 折。折扣互斥,取最优。

TDD 完整流程

flowchart TB A[描述需求] --> B[生成测试用例] B --> C[运行测试 红] C --> D[生成最小实现] D --> E[运行测试 绿] E --> F{需要重构?} F -->|是| G[重构优化] G --> E F -->|否| H[diff 审查] H --> I[review 审查] I --> J[提交代码]

Step 1:设定上下文

/src/lib/discount.ts 还不存在。帮我用 TDD 的方式实现折扣计算:
- 满 100 减 10
- 满 200 减 30
- 满 500 打 8 折(80%)
- 折扣互斥,自动选最优
先写测试,再写实现。用 Vitest。测试文件放在 tests/lib/discount.test.ts

Step 2:Codex 的行为

Codex 会:

  1. 创建 tests/lib/discount.test.ts,包含边界测试用例:
    • 0 元、50 元(无折扣)
    • 100 元(减 10)、150 元(减 10)
    • 200 元(减 30)、400 元(减 30)
    • 500 元(8 折)、1000 元(8 折)
    • 边界交叉:120 元时减 10 vs 可能的其他折扣
  2. 运行测试——全部失败(红)
  3. 创建 src/lib/discount.ts,实现 calculateDiscount 函数
  4. 运行测试——全部通过(绿)

Step 3:你的审查

/diff  # 查看 Codex 的改动

审查重点:

  • 折扣规则是否用配置而非硬编码?(方便未来修改)
  • 边界条件是否覆盖?(0 元、负数、超大金额)
  • 类型定义是否清晰?

如果发现实现不够灵活,追加 prompt:

把折扣规则提取成配置数组,按优先级排序,方便未来添加新规则。重新跑测试。

Step 4:重构(TDD 第三步)

现在实现是对的,但 calculateDiscount 函数可以用策略模式重构,让每个折扣规则独立。

Codex 重构代码,保持测试通过。这就是完整的 TDD 闭环——Codex 帮你走了三轮(红→绿→重构),你只需要在每个节点做审查决策。

高效 Prompt 模板

用 TDD 实现 [功能描述]。先写测试覆盖 [边界条件],再写最小实现,最后重构优化 [具体方向]。测试框架用 [框架名]。

案例 2:Bug 追踪修复——从复现到回归

场景:用户反馈"点击保存按钮后,页面显示'已保存'但刷新后数据丢失"。你怀疑是 API 调用或状态管理的问题。

Step 1:提供完整的复现信息

Bug:设置页面的"保存"按钮有时不持久化数据。

复现步骤:
1. 启动开发服务器:bun run dev
2. 访问 /settings
3. 切换"启用通知"开关
4. 点击"保存"
5. 刷新页面——开关恢复为关闭状态

相关文件可能是:
- src/app/settings/page.tsx
- src/lib/api/settings.ts
- src/server/settings/handler.ts

约束:
- 不改变 API 接口定义
- 修复最小化
- 添加回归测试

Step 2:Codex 诊断过程

Codex 会:

  1. 读取三个相关文件
  2. 追踪数据流:UI → API 调用 → 服务端处理 → 数据库写入
  3. 定位根因——例如发现 api/settings.tsfetch 没有 await,导致 Promise 未被等待
  4. 修复代码
  5. 添加针对此 bug 的回归测试
  6. 运行现有测试确保无回归

Step 3:验证修复

要求 Codex 复现验证:

修复后重新运行复现步骤。运行完整的测试套件确认回归。输出测试结果。

高效 Bug 修复 Prompt 模板

Bug:[一句话描述]

复现步骤:
1. [步骤1]
2. [步骤2]
预期:[应该发生什么]
实际:[实际发生了什么]

可能相关的文件:
- [文件1路径]
- [文件2路径]

约束:
- [不要做什么]
- [必须保持什么]

先定位根因,再修复,最后添加回归测试。

案例 3:安全重构——大型模块的分步改造

场景src/server/auth.ts 中有 500 行代码,混合了认证逻辑、用户管理、权限检查。需要拆分为三个模块:auth/authenticate.tsauth/users.tsauth/permissions.ts

Step 1:先用 /plan 制定方案

/plan 将 src/server/auth.ts(500行)按职责拆分为三个模块:
1. auth/authenticate.ts — 登录、token 验证
2. auth/users.ts — 用户 CRUD
3. auth/permissions.ts — 角色和权限检查

要求:
- 保持所有现有测试通过
- 不改变对外 API
- 每拆分一个模块就跑一次测试
- 列出所有调用方和需要更新的 import

Step 2:审查方案

Codex 输出方案:

  1. 分析 auth.ts 的依赖关系——哪些函数被哪些文件引用
  2. 先拆分 authenticate(被引用最少,最独立)
  3. 再拆分 users
  4. 最后拆分 permissions(依赖前两个)
  5. 每一步:移动代码 → 更新 import → 运行测试

你审查方案后确认执行。

Step 3:分步执行,步步验证

Codex 按方案逐步执行。关键:每一步完成后都运行 bun run typecheck && bun run test

如果某一步测试失败,Codex 会停下来让你决策——而不是继续往前冲导致更多问题累积。

Step 4:重构后审查

/review

对比重构前后的代码:模块行数从 500 降到 3×~150,每个模块职责单一,测试覆盖率保持不变。

安全重构 Prompt 模板

/plan 重构 [目标文件/模块]:[重构目标]

约束:
- 保持所有现有测试通过
- 不改变对外接口
- 分步骤执行,每步后运行测试验证
- 列出所有受影响的调用方

社区推荐的高效 Prompt 模式

基于社区反馈总结的四个黄金模式:

模式 1:GCCD 框架

Goal: [要达成什么]
Context: [涉及哪些文件、什么背景]
Constraints: [必须遵守的约束]
Done: [什么条件下算完成]

模式 2:先问后做

在开始实现之前,先问我三个关于需求边界的问题。

这迫使 Codex 在动手前澄清模糊点,避免方向性错误。

模式 3:自我验证

每完成一个步骤后,运行 [验证命令] 并报告结果。如果失败,不要继续下一步。

防止 Codex 在错误的基础上继续累积问题。

模式 4:多方案对比

给出两种实现方案,对比它们的优缺点,让我选择后再实现。

适合设计决策场景——和 /fork 探索不同方向的思路一致。


日常开发的完整检查清单

开发完成后,跑这个清单:

  1. /diff — 确认改动范围符合预期
  2. /review — 代码审查
  3. 手动确认:业务逻辑是否符合需求
  4. 运行完整 CI 流水线(如果在 Cloud Tasks 中则自动)
  5. 提交并关联 Issue/PR

下一章:A3: Codex 代码审查与质量保障

实操清单

  • 用 TDD 方式让 Codex 实现一个新函数:先描述测试,再描述实现
  • 用 GCCD 框架(Goal/Context/Constraints/Done)写一个完整的 prompt
  • 遇到 Bug 时,用"复现步骤 + 相关文件 + 约束"模板让 Codex 定位和修复
  • /plan 规划一次重构,审查方案后再执行
  • 重构过程中,每完成一个子步骤就运行测试验证
  • 尝试"先问后做"模式:让 Codex 在动手前向你提问
  • 开发完成后跑完整检查清单:/diff/review → 手动确认 → 测试 → 提交