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

"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 単体テストと TDD と Vitest 実践ガイド を参照してください。
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 が緩くなっている(toBe → toBeTruthy) | テスト 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 Actions | Status 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 も完了している必要があります。
フローのチェックリスト
- ローカルテストが全グリーン:Codex が 3 フェーズを完了し、証拠パッケージを出す
- review pane で diff を確認:テストファイルが変更されていないかを見る
- PR を作成:feature branch に push する
- required status checks を通す:CI がフルテスト、typecheck、lint を実行する
- 人間が 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 CI と GitHub Actions Workflow 基礎 を参照してください。PR review の流れは、同シリーズの Codex AI コードレビュー記事で扱います。
CI 失敗の自動修正に置く境界
codex exec と Codex GitHub Action は CI の失敗テストを扱えます。ただし、安全境界が必要です。
失敗テストの自動修正フロー
Codex non-interactive ドキュメントによると、CI 失敗の自動修正フローは次のようになります。
- まずテストを実行して失敗を再現する
- Codex に最小修正をさせる
- patch artifact を生成する
- 修正コードを分離した 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: テスト項目を列挙する
Codex に最小動作、境界条件、回帰シナリオを列挙させます。実装コードは書かせません。 - 2
ステップ 2: 失敗するテストを書く
Codex にはテストファイルだけを変更させ、関連テストを実行して red を確認します。 - 3
ステップ 3: 最小実装に進む
Codex にテスト assertion を変更させず、実装コードだけを修正して同じテストを再実行させます。 - 4
ステップ 4: 全グリーン後にリファクタリングする
テストが通ってから構造を整理し、もう一度テストを実行します。 - 5
ステップ 5: 証拠と diff を確認する
コマンド出力、テストファイルの変更、review pane または PR diff、CI status checks を確認します。
FAQ
Codex は単体テストを書けますか?
Codex に本当にテストを実行させるには?
テストが失敗したとき、Codex はテストを直してよいですか?
カバレッジの数字は品質基準になりますか?
フロントエンド画面はどう検証しますか?
Codex を TDD で動かさないほうがよい場面は?
7分で読めます · 公開日: 2026年7月30日 · 更新日: 2026年7月30日
Codex 実践シリーズ: CLI、デスクトップ App、Cloud、チーム運用
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。



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