目次
AI 時代の TDD は廃れたのか
「コードは AI が書くのだから TDD は不要」という意見を耳にすることが増えました。実務に AI を組み込んで分かったのは TDD は廃れるどころか、AI 駆動開発の最も重要な前提になる ということです。AI 駆動開発そのものの全体像は AI 駆動開発とは?従来開発との違い・進め方 で解説しているので、本記事ではその中核をなすテスト先行の進め方に絞ります。
理由は次のとおりです。
- AI 生成コードの品質を保証するのは結局テスト
- テストを先に書くと、AI が実装の方針を誤らない
- AI が「設計」を勝手にすり替えるのを防げる
- リファクタ後の挙動を継続的に検証できる
- 後任エンジニアへの引き継ぎが、テストという形で残る
特に AI ペアプログラミング の文脈では、人間と AI の役割分担を明確にする最善のツールが「テスト」です。
AI 駆動 TDD の基本フロー
flowchart LR
S["ユーザーストーリー<br/>(人間)"]
T["受け入れテスト設計<br/>(人間 + AI)"]
R["失敗するテスト実装<br/>(AI / 人間レビュー)"]
G["実装を書く<br/>(AI / 人間レビュー)"]
RF["リファクタリング<br/>(AI 提案 → 人間判断)"]
CI["CI 全テスト確認"]
S --> T --> R --> G --> RF --> CI
ポイントは 「テストの設計まで人間が握る」 こと。テストの作成まで AI に丸投げすると、AI が自分の実装に都合の良いテストを書き始めて、Red にならない不健全な TDD になります。
各ステップで「誰が決め、誰が書き、誰がレビューするか」を厳密に整理すると、以下のようになります。
| ステップ | 決める人 | 書く人 | レビューする人 |
|---|---|---|---|
| ユーザーストーリー | 人間 (PdM / PO) | 人間 | チーム |
| 受け入れテスト | 人間 (Tech Lead) | 人間 + AI 補助 | チーム |
| 失敗するテスト | 人間 (テスト設計者) | AI | 人間 |
| 実装 | テストが決める | AI | 人間 |
| リファクタリング | 人間 (Tech Lead) | AI | 人間 |
「決める人」と「書く人」を分けるのが、AI ペアプログラミングを破綻させないコツです。
具体的なテストドキュメントの形
// tests/orders/out-of-stock.spec.ts
import { describe, expect, test } from "vitest";
import { api } from "../_test/api";
import { monitor } from "../_test/monitor";
import { orderRepository, seedProduct } from "../_test/seed";
/**
* 受け入れ基準:
* - 商品在庫が 0 のとき、注文 API は 409 Conflict を返す
* - そのとき注文レコードは生成されない
* - 監視ログに `out_of_stock` イベントが記録される
*/
describe("POST /orders — 在庫切れシナリオ", () => {
test("409 を返し、副作用が安全に止まる", async () => {
// arrange
await seedProduct({ id: "P-001", stock: 0 });
// act
const response = await api.post("/orders", {
productId: "P-001",
quantity: 1,
});
// assert (HTTP)
expect(response.status).toBe(409);
expect(response.body).toEqual({
error: "out_of_stock",
productId: "P-001",
});
// assert (persistence)
const persisted = await orderRepository.findByProduct("P-001");
expect(persisted).toEqual([]);
// assert (observability)
expect(monitor.events()).toContainEqual({
kind: "out_of_stock",
productId: "P-001",
});
});
});このように 受け入れ基準を JSDoc に書く と、AI が実装と監視ログの双方を整合性のある形で生成しやすくなります。Arrange / Act / Assert のコメントを残しておくのも、AI が「テストの意図」を保ったままリファクタしてくれる助けになります。
受け入れ基準は 3 軸で書く
FIXIT が使っているテンプレートは以下の 3 軸です。
- HTTP / インターフェース層 (ステータスコード、レスポンスボディ)
- 永続化 (DB / Cache / Queue がどう変わったか)
- 観測性 (ログ・メトリクス・イベントが意図通り出ているか)
「動いたかどうか」は HTTP のみで判定する人が多いですが、永続化と観測性まで含めてアサート するのが、AI 生成コードを安心して本番投入するための必要条件です。
チーム導入の 4 ステップ
flowchart LR
S1["1. 1 ドメインで実証"]
S2["2. モブプロで型を見せる"]
S3["3. PR テンプレートを更新"]
S4["4. 失敗事例集を共有"]
S1 --> S2 --> S3 --> S4
Step 1. まず 1 つのドメインで AI 駆動 TDD を試す
複数ドメインで一気に始めると、レビュー観点がバラついて失敗します。1 ドメイン (例えば「注文」「在庫」など) に絞って 2 週間 やってみるのが現実的なスタートです。
Step 2. ライブコーディング / モブプロで形を見せる
「テスト先行 × AI 実装」のフローは、口で説明するより、見せた方が伝わります。FIXIT のクライアントワークでも、最初の 1 週間は週 2 回 90 分のモブプロを実施するパターンが定着しました。
Step 3. PR テンプレートに「受け入れテストの設計者」を明記する
PR テンプレートに
### 受け入れテストの設計者
- @username
### Arrange/Act/Assert の 3 軸が揃っているか
- [ ] HTTP / インターフェース
- [ ] 永続化
- [ ] 観測性
を入れると、レビュアーがチェックする観点が揃います。
Step 4. 失敗パターンを失敗事例集として共有する
失敗事例は隠したくなりますが、共有するほどチーム全体の学習が加速します。Notion / esa / Slack で 「Red にならなかった事例集」 を運用しているチームは、半年後の品質が明確に違います。
失敗パターン
パターン A: テストを後付けしてしまう
「先に動くコードを書いて、後でテストを足す」と、AI は実装を後出しジャンケンで通す形でテストを書いてしまいます。これは TDD ではなく、AI に Green を装わせているだけです。「テストが Red になることを目で確認してから実装に入る」 ルールを徹底するだけで、ほぼ防げます。
パターン B: テストが粗すぎる
「正しく動く」程度のテストでは、AI は適当な実装で通してしまいます。境界値・例外系・副作用 (ログ・外部 API・DB) まで明示しましょう。Arrange / Act / Assert の 3 軸 が揃っているかを PR テンプレートでチェックすると、粒度が揃います。
パターン C: 大きすぎるストーリー
1 つのストーリーに 10 個以上の受け入れ基準が並ぶと、AI が一気にコードを書き、レビュー困難になります。1 ストーリーは 30 分以内で実装できる粒度 が経験則です。それを超えるなら、ストーリーを分割してください。
パターン D: テストの「品質」を測らない
カバレッジだけ追って、「Mutation Testing」「Property-Based Testing」のような テストの品質 を測る指標を入れないと、テストが形骸化します。FIXIT では中規模以上のプロジェクトで Stryker / fast-check を導入することが多いです。
効果を測る 3 つの KPI
AI 駆動 TDD の効果を、感覚論ではなく数字で示す KPI です。
| KPI | 目標 | 計測方法 |
|---|---|---|
| テスト先行率 | 80%+ | PR のうち、テストコミットが実装コミットより先のもの |
| PR 中央サイズ | 200 LOC 以下 | GitHub の Insights から計測 |
| 本番障害 P1 / 月 | 0〜1 件 | インシデント管理ツールから集計 |
特に「テスト先行率」を KPI に入れると、後付けテストの誘惑が減ります。AI 駆動 TDD を組織導入するときは、この 3 つのうち最低 1 つは公開ダッシュボードで見えるようにすると効果的です。
よくある質問
Q. AI 駆動 TDD は学習コストが高そうですが、ペイしますか?
A. 既に TDD を実践しているチームなら 1〜2 週間でフロー切り替えが完了します。TDD 未経験のチームでは、TDD のオンボーディング + AI フローのオンボーディング を並行で進めるため 4〜6 週間が目安。ペイ期間はおおむね 3 ヶ月以内、リリース速度の差で確認できます。
Q. AI に書かせたテストは、人間が書いたテストより劣りますか?
A. 受け入れ基準を人間が書く のなら、品質はほぼ同等になります。AI に渡すのは「失敗するテストの実装」レイヤーであり、テストの意図そのものは人間が握っているからです。
Q. テストファーストが向かない領域はありますか?
A. 探索的な UI 実装、AI モデルのプロンプトチューニング、外部 API の仕様調査などは TDD の優先度を下げて構いません。とはいえ コアドメイン は AI 駆動 TDD で書く価値が高いです。
関連リソース
- AI 駆動開発の全体像は AI 駆動開発とは で解説しています
- AI 駆動 TDD を実プロジェクトで使った事例は SaaS MVP を 3 週間で本番投入したスタートアップ案件 を参照してください
- Claude Code 自体の組織導入は Claude Code 導入完全ガイド を併読ください
- Cursor とのペア導入は Cursor を中規模チームに導入する手順と落とし穴 で扱っています
- ワークショップやコンサルティングのご相談は お問い合わせ からどうぞ
