Codex CLI 完全指南:第十一章·测试自动化与 CI/CD 集成

测试是软件质量的最后防线,CI/CD 是高效交付的基础设施。本章讲解如何使用 Codex 自动化测试编写、修复和 CI/CD 管道中的智能集成。

测试自动化

根据源码生成测试

# 为单个文件生成测试
codex "为 src/services/PaymentService.ts 编写完整的单元测试:
  - 框架:Vitest
  - 覆盖场景:正常支付、余额不足、网络超时、重复支付
  - Mock:PaymentGateway 和 NotificationService
  - 使用 describe/it 结构
  - 每个测试用例有清晰的意图描述"

增量测试

只对新变更的代码生成测试,而不是全量覆盖:

git diff main...HEAD --name-only | while read file; do
  if [[ "$file" == src/services/*.ts ]]; then
    echo "为 $file 生成测试..."
    codex exec --yes "为 $file 中新增的方法编写测试,使用项目现有的测试框架"
  fi
done

测试数据生成

codex "为 UserService 的测试生成 10 组测试数据(fixture):
  - 2 个正常用户
  - 2 个缺失必填字段的用户
  - 2 个数据格式不合规的用户
  - 2 个边界值用户(最长/最短名称)
  - 2 个特殊字符用户

  格式:TypeScript 对象数组,包含 id、email、name、role"

测试用例多样化

AI 可以系统性地构造测试用例的变体:

codex "对于 validateEmail 函数,使用等价类划分法生成测试用例:
  1. 有效等价类:标准邮箱、含数字、含点号、含加号
  2. 无效等价类:无@、无域名、含空格、空字符串、超长
  3. 边界值:1个字符长度、254个字符长度(RFC 5321 上限)"

快照测试更新

# 当 UI 组件发生合法变更后,更新快照
codex "我修改了 Button 组件的样式。运行测试后快照失败了。\n
  请检查失败的快照,判断变更是否合理:
  - 如果合理,更新快照
  - 如果不合理,修复代码使快照通过"

E2E 测试

codex "为登录流程编写 Playwright E2E 测试:
  1. 访问 /login
  2. 输入 test@example.com / Test1234
  3. 点击登录按钮
  4. 验证跳转到 /dashboard
  5. 验证页面显示用户名
  6. 添加错误场景:错误密码、空表单"

测试覆盖率分析

npx vitest --coverage 2>&1 | codex exec \
  "分析测试覆盖率报告:
   1. 列出覆盖不足的文件(<80%)
   2. 对每个文件,指出未覆盖的函数或分支
   3. 按业务重要性排序,优先为关键路径补充测试"

突变测试

codex "我对这个函数做了一个小改动(引入一个 bug),测试全部通过了。\n
  这说明测试覆盖不足。请分析原因并补充能发现这个 bug 的测试。"

# Codex 会分析为什么现有测试没有捕获这个变化

CI/CD 集成

GitHub Actions 集成

# .github/workflows/codex.yml
name: Codex AI Pipeline

on:
  pull_request:
    types: [opened, synchronize]
  issue_comment:
    types: [created]

jobs:
  code-review:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install Codex
        run: curl -fsSL https://opencode.ai/install | bash

      - name: Codex PR Review
        run: |
          gh pr diff ${{ github.event.pull_request.number }} | \
          codex exec --yes \
            "审查此 PR。按以下格式输出 Markdown 报告:\n
             ## PR 审查\n
             ### 发现问题\n
             ### 建议\n
             ### 风险点\n
             如果发现严重问题(安全漏洞、数据丢失风险),以非零退出码退出。"
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

  fix-tests:
    if: failure() && github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci

      - name: Run Tests & Collect Failures
        run: npm test 2>&1 | tee test-output.txt
        continue-on-error: true

      - name: Codex Fix Failing Tests
        run: |
          cat test-output.txt | codex exec --yes \
            "这些测试失败了。分析原因(是测试本身写错了还是源码有 bug),修复源码。不要修改测试文件。"
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

  generate-changelog:
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 50

      - name: Generate Changelog
        run: |
          git log --oneline -50 | codex exec \
            "基于 Git 提交历史生成 CHANGELOG.md:
             ## [版本号] - 日期
             ### Added
             ### Changed
             ### Fixed
             ### Deprecated"
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

自动修复工作流

当 CI 检测到问题后,自动触发 Codex 修复:

auto-fix:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4

    - name: ESLint Auto Fix
      run: npx eslint src/ 2>&1 | tee eslint-errors.txt
      continue-on-error: true

    - name: Codex Fix ESLint
      run: |
        if [ -s eslint-errors.txt ]; then
          cat eslint-errors.txt | codex exec --yes \
            "修复这些 ESLint 错误。保持代码逻辑不变,仅修复 lint 问题。"
        fi

    - name: TypeScript Check
      run: npx tsc --noEmit 2>&1 | tee tsc-errors.txt
      continue-on-error: true

    - name: Codex Fix Type Errors
      run: |
        if [ -s tsc-errors.txt ]; then
          cat tsc-errors.txt | codex exec --yes \
            "修复这些 TypeScript 类型错误。分析根本原因,避免使用 any 或类型断言绕过。"
        fi

    - name: Create Fix PR
      uses: peter-evans/create-pull-request@v6
      with:
        title: "🤖 Auto-fix: Codex 自动修复"
        body: "Codex 自动修复了以下 CI 错误:\n- ESLint\n- TypeScript"

GitLab CI 集成

# .gitlab-ci.yml
codex-review:
  image: node:20
  script:
    - curl -fsSL https://opencode.ai/install | bash
    - git diff origin/main...HEAD | codex exec --yes "审查代码变更"
  only:
    - merge_requests

部署命令生成

# 分析当前项目结构,自动生成部署脚本
codex "分析 Dockerfile 和 docker-compose.yml,生成一键部署脚本:
  - 构建镜像
  - 运行数据库迁移
  - 健康检查
  - 蓝绿部署切换
  - 回滚命令"

环境配置同步

codex "对比 .env.example 和 .env.production:
  1. 列出 production 中缺失的新配置项
  2. 列出 production 中不应存在的开发配置
  3. 给出需要运维手动填写的配置清单"

完整 CI/CD 质量流水线

一个完整的 Codex 增强的 CI/CD 流水线:

PR 创建
  │
  ├── [Lint 检查] → Codex 自动修复
  │
  ├── [类型检查] → Codex 自动修复类型错误
  │
  ├── [单元测试] → Codex 修复失败的测试
  │
  ├── [Codex 审查] → 安全/性能/架构分析报告
  │
  ├── [集成测试] → Codex 修复失败
  │
  └── [合并到 main]
       │
       ├── [构建] → Codex 生成 Changelog
       │
       ├── [部署] → Codex 监控部署日志
       │
       └── [生产监控] → Codex 分析错误报告

注意事项

API 费用:CI/CD 中的 Codex 调用会产生 API 费用,注意设置速率限制

安全审查:AI 自动修复的代码仍然需要人工审查,尤其是涉及安全和数据的修改

修复范围:限定 Codex 只能修改特定目录或文件类型

超时控制:在 CI 中设置 Codex 命令的超时,防止长时间分析阻塞流水线

密钥管理:使用 GitHub Secrets 存储 API Key,永远不要硬编码

小结

测试自动化解决了"写测试太累"的问题,CI/CD 集成解决了"问题发现太晚"的问题。将 Codex 嵌入 CI 流水线后,你的 PR 在创建那一刻就能获得 AI 代码审查和自动修复——质量左移,交付加速。