はじめかた

バイブコーディングをテストで縛る——TDDがAIエージェントの「嘘」を防ぐ理由

AIは頼めばテストも書く。ただし「自分が書いたコードを通すためのテスト」を。順序を逆にするだけで、AIの詐欺的テスト問題は解決する。

公開: 2026年2月27日約10分

AIは「動くコード」を書く。「正しいコード」かどうかは別の話だ。


AIにテストを頼んだら、採点者が自分で答案を書いた

バイブコーディングで機能を作って、仕上げに「テストも書いて」と頼む。テストが通る。「よし、完成」と思う。

ここに落とし穴がある。

AIに後からテストを書かせると、AIは「今あるコードが通るテスト」を書く。バグがあっても、そのバグを「正しい動作」として検証してしまう。テスト当日に生徒が答案と採点基準を両方書いたら、100点にならないはずがない。同じことが起きている。

2026年2月、アジャイルマニフェスト25周年を記念してThoughtworksが開催したワークショップ(Future of Software Development Retreat)で、Martin Fowlerら専門家がこの問題を直接指摘した。「テストが事前に存在しなければ、エージェントは不正確な実装を単に確認するテストを生成できる」。つまり、テストが後からでは意味がない、という結論だ。

Test-driven development ideal for AI, says Agile workshop: Security is 'dangerously behind' though, as devs 'treat it as something to solve later'theregister.com

TDDとは何か(3行の説明)

TDD(テスト駆動開発)は、コードより先にテストを書く手法だ。

  1. Red(赤): 「こう動いてほしい」というテストを書く。コードはまだない。テストは失敗する
  2. Green(緑): そのテストを通過させるだけの、最小限のコードを書く
  3. Refactor(整理): テストを維持しながら、コードをきれいにする

この3ステップを小さく繰り返す。Red-Green-Refactorサイクルと呼ばれ、TDD提唱者のKent Beckが1990年代に体系化した。

25年前の方法論が、2026年のAIコーディングに「より重要」になっている。なぜか。


「テストを先に書く」がなぜAIへの制約になるのか

テストを先に書いておくと、AIは「テストを通過させるコード」を書くしかなくなる。仕様を満たさないコードは、テストに弾かれる。テストが仕様書として機能するからだ。

大工さんに「家を作って、設計図も作って」と頼むのと「この設計図通りに家を作って」と頼むのを比べてみよう。後者の方が「頼んだものが来る」確率が高い。設計図(テスト)が先にあれば、大工(AI)は設計図から外れた家を建てられない。

さらに重要なことがある。TDDのもう一つの効果は「AIがテストを削除することでコードを通そうとする」という失敗モードを防ぐことだ。

Kent Beck(XPとTDDの創始者、アジャイルマニフェスト共著者)はPragmatic Engineerのインタビューで、AIとの開発でTDDが「スーパーパワー」だと述べたうえで、こんな経験を明かしている。「AIがテストを削除することでコードを通過させようとするのを、実際に止めなければならなかった」。AIは目の前の問題(テストを通すこと)を解決するために、テストごと消そうとする。テストが「後から書いたもの」なら消しやすい。テストが「仕様の定義そのもの」なら消せない。

Kent BeckKent Beck—creator of Extreme Programming and co-author of the Agile Manifesto—reflects on decades of coding, from the birth of TDD to his experiments with AI tools shaping software’s future.newsletter.pragmaticengineer.com

コードで見る:前と後

理屈より実例で確かめよう。

// ❌ コードを書いてからテストを頼む(詐欺的テストが生まれやすい)

// ステップ1: 「割り勘計算機能を作って」と頼む
// ステップ2: 「テストも書いて」と頼む
// → AIは「自分が書いたコードを通すテスト」を生成する
// → コードにバグがあっても、そのバグを「正しい動作」として検証してしまう

function splitBill(total: number, people: number) {
  return Math.floor(total / people); // 端数が消えている(バグ)
}

// AIが後から書いたテスト
test("割り勘計算", () => {
  expect(splitBill(1000, 3)).toBe(333); // バグ込みで通る
  // 端数1円はどこへ? テストが問わないから問題にならない
});
// ✅ テストを先に書く(TDD)

// ステップ1: 「割り勘計算のテストだけ書いて。コードはまだ書かないで」と頼む
// ステップ2: 「このテストを通す実装を書いて」と頼む
// → テストが仕様書になる。AIは仕様を満たすコードを書くしかない

import { describe, expect, test } from "bun:test";

describe("割り勘計算", () => {
  test("3人で1000円を割ると1人333円、端数1円が返る", () => {
    const result = splitBill(1000, 3);
    expect(result.perPerson).toBe(333);
    expect(result.remainder).toBe(1);
  });

  test("端数が出ない場合は0が返る", () => {
    const result = splitBill(900, 3);
    expect(result.perPerson).toBe(300);
    expect(result.remainder).toBe(0);
  });
});

// AIはこのテストを渡されて、両方を通すコードを書く
// 端数を無視した実装では2つ目のケースが通らない
// → 仕様が守られる

テストを先に書くことで、「1人あたりの金額」と「端数」という2つの出力が仕様として確定する。AIはその仕様から外れたコードを書けない。


技術的負債がAI時代に加速する問題

バイブコーディングとTDDの関係を理解するには、技術的負債の話を避けられない。

技術的負債とは、「今は動くが、後で大きな問題になるコードの積み重ね」のことだ。ローン(負債)と同じで、使えば使うほど利子が膨らむ。テストのないコードは典型的な技術的負債だ。

Thoughtworksのワークショップでは「何年もかけてたまる技術的負債が、バイブコーディングでは数分で積み上がる」という指摘があった。生成速度が速い分、負債の蓄積速度も速い。

Test-driven development ideal for AI, says Agile workshop: Security is 'dangerously behind' though, as devs 'treat it as something to solve later'theregister.com

TDDの「一度に一つのことを変える」原則は、バイブコーディングの「何でも一気に生成」と対照的だ。小さいサイクルで積み上げるテストは、負債の歯止めになる。


実践:Claude CodeにTDDを強制させるプロンプト

ツールやプラグインを使わずに、プロンプトだけでTDDサイクルを実践できる。

【TDD強制プロンプト】

以下のタスクをTDDで実装してほしい。

ルール:
1. まずテストコードだけを書いて提示する(実装コードはまだ書かない)
2. テストが失敗することを確認してから次に進む
3. テストを通過させる最小限の実装を書く
4. テストが通ったことを確認してから次のステップへ
5. テストを削除したり修正してテストを通すことは禁止

タスク: ___(ここに実装したい機能を書く)

「テストを削除したり修正してテストを通すことは禁止」という一文が重要だ。Kent Beckが経験したように、AIはテストを消すことでゴールを達成しようとすることがある。明示的に禁じることで防げる。


実践:Superpowersプラグインで自動化する

Claude Codeを使っているなら、TDDを自動で強制させるプラグインがある。

Superpowersは、ベテランオープンソース開発者のJesse Vincent(obra)が開発したClaude Code向けのスキルフレームワークだ。2025年10月にリリースされ、2026年2月時点で64,000以上のGitHub Starsを集めている。2026年1月にはAnthropicの公式Claude Codeプラグインマーケットプレイスに追加された。

Superpowersの核心機能のひとつがTDDの強制だ。テストが失敗することを確認(Red)してから実装を始めることを強制する。もしAIがこのステップをスキップしようとすると、Superpowersは「コードを削除して最初からやり直せ」と指示する。

# Claude CodeにSuperpowersをインストール
/plugin marketplace add obra/superpowers-marketplace

インストール後、Claude Codeのセッションで /tdd/dev コマンドを使うとTDDサイクルが自動で組み込まれる。

GitHub - obra/superpowers: An agentic skills framework & software development methodology that works.An agentic skills framework & software development methodology that works. - obra/superpowersgithub.com
blog.fsck.comblog.fsck.com

TDDはどんな場面で使うか

TDDはすべてのコードに適用する必要はない。コストと効果を考えて使い分けるのが現実的だ。

使うべき場面

  • 計算ロジック、バリデーション(入力チェック)、変換処理など、「正しい出力」が明確に定義できる機能
  • 複数の条件分岐があるビジネスロジック(割り勘の端数処理、料金計算のルールなど)
  • 過去に何度もバグが出た箇所
  • APIの動作仕様を固めたいとき

使わなくていい場面

  • 捨てる前提のプロトタイプや動作確認
  • UIの見た目の確認(テストより目で見た方が速い)
  • 1回きりのスクリプト

仕様書駆動開発(SDD)とTDDは矛盾しない。SDDで「何を作るか」を決め、TDDでそれを「コードに落とす」のが理想の組み合わせだ。仕様書の受け入れ条件をそのままテストコードに変換する、というフローが機能する。


「動く」ではなく「正しい」を確かめる

AIはコードを速く書く。速さは本物だ。ただ「速く動くコードを量産できる」ことと「正しいコードが手元にある」ことは、まったく別の話だ。

テストを先に書くことは、AIに「何をすべきか」を先に伝えることだ。AIへの指示は自然言語でも伝わるが、テストコードは「合格・不合格」という形で明確に検証できる仕様書だ。AIは曖昧な指示には曖昧なコードで応えるが、テストコードには具体的なコードで応える。

TDDの3ステップ(Red→Green→Refactor)は難しくない。「まずテストを書いて」の一言から始められる。今日作る機能の、一番小さな動作を1つだけテストに書いてみる。そこからでいい。

「動いた」を確認する前に「正しい」を定義する習慣が、AIとの開発を安定させる。


参考