テーマを切り替える

Codex のテスト駆動開発:AI に先にテストを書かせ、全グリーンまで直す

Easton editorial illustration: Codex project workflow bench

"OpenAI Codex Best practices は、Goal、Context、Constraints、Done when を明確にし、テスト、チェック、review を完了条件に入れることを勧めています。"

ターミナルで Codex が「すべてのテストに合格しました」と出している。でもよく見ると、結論だけで、実行したコマンドも、どのテストを走らせたのかも書いていません。diff を開くと、テストファイルまで変わっています。assertion が toEqual(42) から toBeTruthy() になっている。Codex を疑っているのではありません。証拠のない「全グリーン」を信じられないだけです。この記事では、再利用できる操作テンプレート、証拠の受け取り方、防偽グリーンの guardrail をまとめます。「AI を信じる」を「再現できる証拠を見る」に変えるための手順です。

Codex では、なぜテスト先行がより重要なのか

テスト先行は、単に「先にテストを書いてからコードを書く」ことではありません。Codex を使うとき、テストは機械が実行できる受け入れ条件になります。Codex はコマンドを実行し、出力を読み、ファイルを変更できます。ただし、「完了」の基準は事前にこちらが明確にする必要があります。

OpenAI Codex の公式ドキュメントでは、検証できる作業ほど Codex の出力品質が上がるとされています。つまり、どのように検証するか、どのコマンドを使うか、期待する結果は何かを伝えるほど、正しい変更に近づきます。曖昧な依頼は曖昧に処理されがちです。小さなタスクほどテストしやすく、review もしやすくなります。

red-green-refactor の 3 段階ループは次のとおりです。

フェーズCodex がやることあなたが見る証拠
Redテストだけを書く。実装は書かない失敗したテスト名、失敗した assertion
Green最小実装を行う。テストは変更しない通ったテスト、変更ファイル一覧
Refactor構造を整理し、テストを再実行するまだ全グリーンで、diff にテストファイルがない

この 3 つは省けません。red を飛ばすと、そのテストが本当に新しい挙動を検証しているのかわかりません。refactor を飛ばすと、継ぎはぎのコードが残りやすくなります。Codex の基本は Codex 完全入門ガイド も参考になります。

Red Phase:Codex に失敗できるテストだけを書かせる

Red phase の中心は制約です。テストファイルだけを変更し、実装コードは書かない。まず Codex にテスト項目を列挙させ、1 つずつ生成し、最後にテストを実行して red を確認します。

Prompt テンプレート

テストファイルだけを変更してください。実装コードは変更しないでください。
[機能名] について、次のテストシナリオを書いてください。
1. [最小動作]
2. [境界条件]
3. [エラー経路]
完了後に `npm test` を実行し、失敗したテスト名と assertion を貼ってください。

この prompt には必ず「実装コードは変更しないでください」を入れます。この一文がないと、Codex はテストを書きながら実装もついでに書き、red の検証を壊してしまうことがあります。

Red を確認する

Codex の作業後、完全なテスト出力を求めます。red は期待した assertion で失敗している必要があります。コンパイルエラーや import 失敗で落ちている状態は、良い red ではありません。たとえば次のように出ていれば:

FAIL src/utils/calculator.test.ts > add > should handle negative numbers
AssertionError: expected -1 to be 42

負数入力の挙動をテストしていて、期待した場所で失敗していると判断できます。もし TypeError: Cannot find module 'calculator' だけなら、それはコンパイルエラーであり、テスト失敗ではありません。

テスト項目を並べ替える

Codex に一度で何十個ものテストを生成させないでください。最小動作、境界条件、回帰 bug、エラー経路から始め、1 つずつ進めます。テスト項目は AGENTS.md や別ドキュメントに置き、Codex が順番に処理できるようにします。

単体テストの基本は Vitest 単体テストと TDDVitest 実践ガイド を参照してください。

Green Phase:最小実装で全グリーンまで直す

Green phase の強い guardrail は、テストファイルを変更しないことです。テストが失敗したら、Codex は実装だけを直します。テストを実装に合わせて変更してはいけません。

Prompt テンプレート

実装ファイルだけを変更してください。テストファイルは変更しないでください。
テストを通すための最小変更だけを行ってください。
完了後に `npm test` を実行し、合格概要を貼ってください。

この prompt には必ず「テストファイルは変更しないでください」を入れます。この一文がないと、Codex は assertion を変えたり、テストを削ったり、case を skip したりして、見かけ上グリーンにすることがあります。

合格概要と diff を確認する

Codex の作業後、テスト数、合格数、所要時間を出させます。

PASS src/utils/calculator.test.ts (1.2s)
  add
    ✓ should add two numbers (5ms)
    ✓ should handle negative numbers (3ms)
  2 tests passed

そのうえで diff を確認します。変更ファイル一覧にテストファイルが出ていたら、その green phase は拒否します。

偽グリーンを防ぐ guardrail

TDD で最も危険なのは偽グリーンです。次の 6 つのサインは必ず警戒します。

偽グリーンのサイン防ぎ方
テストファイルが変更されているdiff を確認し、テストファイルを含む green phase は拒否する
assertion が toEqual(42) から toBeTruthy() に変わっているCodex に完全な assertion を出させ、人間が比較する
test.skip() / test.only() が追加されているテストファイルを grep し、新しい skip/only を禁止する
matcher が緩くなっている(toBetoBeTruthyテスト diff を比較し、matcher の緩和を禁止する
fixture が「正解」に書き換えられているfixture の diff を確認し、入力データの変更を禁止する
単体テストだけを走らせ、関連する結合テストを走らせていないDone when に関連するすべてのテストコマンドを含める

これらの guardrail は Codex が自動で守ってくれるものではありません。review 時に人間が確認する必要があります。自動化が進んだチームなら、一部を CI や pre-commit hook に移せます。

Refactor Phase:全グリーン後にだけ整理する

Refactor phase はグリーンになってから始めます。テストが通っていないなら、リファクタリングしません。リファクタリング後は必ずテストを再実行します。diff だけで判断しないでください。

Prompt テンプレート

すべてのテストが通っています。ここからはリファクタリングだけを行ってください。
- 意図がわかりやすいように変数名を変更する
- 重複コードを削る
- 関数を抽出する
テストファイルは変更しないでください。完了後に `npm test` を再実行してください。

この段階で Codex が変えるのは構造だけです。新しいロジックを入れたなら、それは refactor ではなく、新しい挙動の green phase です。

テストを再実行して検証する

リファクタリング後、Codex は同じテストセットをもう一度実行する必要があります。テストが全グリーンのままなら、既存挙動を壊していないと判断できます。失敗した場合は、リファクタリングが挙動を変えたため、戻すか修正します。

diff も確認します。変更ファイル一覧にテストファイルが出てはいけません。出ているなら、refactor の境界を越えています。

リファクタリング例は AI リファクタリングとテストの安全網 を参照してください。

証拠パッケージ:Codex に review 可能な証拠を出させる

各フェーズの終了前に、Codex には次の証拠を出させます。

完了前の受け入れチェックリスト

  • テストコマンドと exit code
  • 失敗/合格の概要
  • 変更ファイル一覧
  • テストファイルが変更されたかどうか
  • CI status checks(ある場合)

完了返信テンプレート

Codex には次の形式で返信させます。

### テスト結果
- コマンド:`npm test`
- Exit code:0
- 合格:42 個のテスト
- 失敗:0
- 所要時間:1.2s

### 変更ファイル
- src/utils/calculator.ts
- (テストファイルは変更していません)

### 残るリスク
- 未カバーの境界条件:負数入力

この形式なら、証拠を読みやすく、比較しやすく、保存しやすくなります。Codex が「テストは通りました」とだけ返した場合、本当にテストを実行したのか、テストファイルを変えたのか、境界条件を漏らしたのか判断できません。

テスト層の選び方とコマンド例

検証したい内容によって、適したテスト層は変わります。いきなり全量 E2E に行く必要はありません。snapshot test だけに頼るのも危険です。

テスト層の判断表

テスト層使う場面コマンド例Codex に出させる証拠
単体テスト1 つの関数を素早く検証するnpm run test:unit または vitest run または pytest失敗したテスト名、assertion
結合テストモジュール間の連携を検証するnpm run test:integration失敗したモジュール、インターフェース
E2E テストユーザーフローを検証するnpx playwright test失敗シナリオ、スクリーンショット
型チェックコンパイル時エラーを拾うnpm run typecheck または tsc --noEmitエラーファイル、行番号
Lintコード規約を確認するnpm run lint または eslintエラーファイル、ルール名
CIチームの gate として使うGitHub ActionsStatus checks ページ

コマンド例は「自分のプロジェクトのコマンドに置き換える」前提です。プロジェクトによって Jest、Vitest、Pytest、Playwright、GitHub Actions は異なります。テストフレームワークの背景は Next.js Jest テストガイド も参考になります。

Codex の最初の検証層には、単体テストが向いています。速く、失敗情報が明確で、AGENTS.md にテストコマンドを書きやすいからです。結合テストと E2E テストは、複数モジュールの連携やユーザーフローの検証に向いています。ただし、失敗原因の切り分けは難しくなります。型チェックと Lint は補助的な検証として、コンパイルエラーやコード規約違反を拾えます。CI はチーム最後の gate です。ローカルテストが全グリーンでも、merge する前に CI status checks の通過を待つ必要があります。

AGENTS.md と prompt にルールを固定する

TDD ルールを AGENTS.md に書いておくと、Codex は作業前に毎回読みます。毎回同じ prompt を書き直す必要がなくなります。

AGENTS.md の小さな例

プロジェクトルートや局所ディレクトリに、次のような内容を置きます。

## Test commands
- Run tests: `npm test`
- Run unit tests: `npm run test:unit`
- Run typecheck: `npm run typecheck`

## TDD rules
- Red phase: only modify test files
- Green phase: only modify implementation files
- Refactor phase: must re-run tests after cleanup

## Done when
- All tests pass
- Test files are not modified in green/refactor phase
- Diff contains only expected changes

このファイルにより、Codex はプロジェクトのテストコマンド、各フェーズで変更してよい範囲、完了条件を把握できます。AGENTS.md の書き方は、同シリーズの Codex プロジェクトルール記事で扱います。

局所ディレクトリには、より具体的なルールを書けます。たとえば src/utils/AGENTS.md には、src/utils/ のテストシナリオ、境界条件、既知の bug を列挙できます。

AGENTS.md に secret、token、機密設定を書かないでください。Codex はこのファイルを読みますが、機密情報を自動で除外するわけではありません。

ローカルからチームへ:CI gate

ローカルテストが全グリーンでも、merge できるとは限りません。チームには CI gate があります。required status checks は通過し、PR review も完了している必要があります。

フローのチェックリスト

  1. ローカルテストが全グリーン:Codex が 3 フェーズを完了し、証拠パッケージを出す
  2. review pane で diff を確認:テストファイルが変更されていないかを見る
  3. PR を作成:feature branch に push する
  4. required status checks を通す:CI がフルテスト、typecheck、lint を実行する
  5. 人間が review:diff、証拠パッケージ、残るリスクを確認する

テスト全グリーンは自動 merge ではない

GitHub Docs では、protected branch に merge するには required status checks が通る必要があると説明されています。ただしリスクがあります。skipped job は success として報告され、required check であっても PR merge を止めません。つまり、実際には一部の check が走っていなくても、PR が merge 可能に見えることがあります。

workflow が skip された偽グリーンを防ぐには、GitHub Checks ページを開き、すべての required checks が本当に実行されたかを確認します。

review pane を使う

Codex app の review pane では、diff にテストファイルの変更が含まれているかを確認できます。file または hunk 単位で stage、unstage、revert できます。テストファイルが変更されていたら、その変更を revert し、実装ファイルの変更だけを残します。

CI の背景は GitHub Actions CIGitHub Actions Workflow 基礎 を参照してください。PR review の流れは、同シリーズの Codex AI コードレビュー記事で扱います。

CI 失敗の自動修正に置く境界

codex exec と Codex GitHub Action は CI の失敗テストを扱えます。ただし、安全境界が必要です。

失敗テストの自動修正フロー

Codex non-interactive ドキュメントによると、CI 失敗の自動修正フローは次のようになります。

  1. まずテストを実行して失敗を再現する
  2. Codex に最小修正をさせる
  3. patch artifact を生成する
  4. 修正コードを分離した PR を開く

npm test 2>&1 | codex exec "失敗原因を要約し、最小修正を提案して" を使えば、テスト出力を Codex に渡し、失敗の要約と修正案を出させられます。

安全原則

Codex に、リポジトリへの書き込み権限と secret へのアクセスを同じ job で同時に持たせないでください。最小権限の sandbox を使います。既定は read-only、書き込みが必要なら workspace-write を作業ディレクトリに限定し、danger-full-access は管理された環境だけで使います。

patch artifact の生成と PR 作成を分離し、信頼できないコードに API key が露出しないようにします。

ここでは完全な GitHub Actions YAML までは展開しません。原則は、最小権限、patch の分離、人間による merge です。自動化の詳細は、同シリーズの codex exec 自動化記事で扱います。

まとめ

Codex のテスト駆動開発の中心は、3 フェーズの操作テンプレートです。Red はテストだけを書く。Green は実装だけを直す。Refactor は整理した後にテストを再実行する。各フェーズでは、コマンド、失敗/合格概要、変更ファイル一覧という review 可能な証拠を必ず出させます。

防偽グリーンの guardrail こそが重要です。テストファイルが変更されていないか、assertion が緩くなっていないか、test が skip されていないか、fixture が変わっていないか、単体テストだけで結合テストを避けていないか、CI workflow が skip されていないかを確認します。

チームで使うなら、ローカルテストの全グリーンだけでは足りません。CI status checks、PR review、protected branch の条件を満たしてから merge します。

次に Codex にコード変更を頼むときは、まずテストを書かせ、red を確認し、それから証拠を見てください。「テストが通りました」という 4 文字だけで止めないことです。

Codex で TDD を 1 サイクル回す

作業を red、green、refactor の 3 ラウンドに分け、Codex に失敗するテストを先に書かせ、最小実装で通し、最後にテスト出力、diff、CI で検証します。

  1. 1

    ステップ 1: テスト項目を列挙する

    Codex に最小動作、境界条件、回帰シナリオを列挙させます。実装コードは書かせません。
  2. 2

    ステップ 2: 失敗するテストを書く

    Codex にはテストファイルだけを変更させ、関連テストを実行して red を確認します。
  3. 3

    ステップ 3: 最小実装に進む

    Codex にテスト assertion を変更させず、実装コードだけを修正して同じテストを再実行させます。
  4. 4

    ステップ 4: 全グリーン後にリファクタリングする

    テストが通ってから構造を整理し、もう一度テストを実行します。
  5. 5

    ステップ 5: 証拠と diff を確認する

    コマンド出力、テストファイルの変更、review pane または PR diff、CI status checks を確認します。

FAQ

Codex は単体テストを書けますか?
書けます。ただし、red が期待した assertion で失敗しているか、境界条件をカバーしているかは人間が確認する必要があります。
Codex に本当にテストを実行させるには?
Done when にテストコマンドと出力提示を明記します。`npm test 2>&1 | codex exec "失敗原因を要約し、最小修正を提案して"` のように、テスト出力を Codex に渡すこともできます。
テストが失敗したとき、Codex はテストを直してよいですか?
Green phase では禁止です。テストが失敗したら、まず失敗原因を要約させ、それから最小の実装修正をさせます。
カバレッジの数字は品質基準になりますか?
カバレッジは信号であって基準ではありません。高いカバレッジでも、assertion が間違った挙動を確認している可能性があります。
フロントエンド画面はどう検証しますか?
Playwright や browser test を使います。Codex に `npx playwright test` を実行させ、失敗シナリオとスクリーンショットを出させることができます。
Codex を TDD で動かさないほうがよい場面は?
探索的なプロトタイプ、一度きりのスクリプト、安定したテスト基盤がないプロジェクトです。そういう場面では、まずコードを直してからテストを補うほうが向いています。

7分で読めます · 公開日: 2026年7月30日 · 更新日: 2026年7月30日

コメント

GitHubアカウントでログインしてコメントできます

Easton BlogEaston Blog