エンジニアリング

AI 駆動 TDD - テストを AI に先に書かせる開発フロー

TDD と AI を組み合わせる「AI 駆動 TDD」のフレームワーク。テスト → 実装 → リファクタリングのループを AI に並走させつつ、品質を落とさず設計判断を人間が握る具体的な方法を、AI 駆動開発のクリエイティブスタジオが共有します。

#TDD#AI 駆動開発#Claude Code#設計#AI ペアプログラミング

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 軸です。

  1. HTTP / インターフェース層 (ステータスコード、レスポンスボディ)
  2. 永続化 (DB / Cache / Queue がどう変わったか)
  3. 観測性 (ログ・メトリクス・イベントが意図通り出ているか)

「動いたかどうか」は 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 駆動開発のご相談はこちら

記事に関連したワークショップ・導入支援も承ります。30 分でフィットするか判断できる無料相談から始めましょう。

30 分の無料相談を申し込む