はじめに
TDDは、昨今AIエージェントによる開発が広まる中で再注目されている開発手法だ。
自分自身も、AI駆動開発の文脈でTDDを勉強し、あえてAIにたよらずTDDを実践してみた。
その中で、TDDは「陣取りゲームに近いのではないか?」と思えてきた。
実際のコードを読んでみたり、太い本を買ったりする前に、ざっくりTDDを知りたいあなたへ。
陣取りゲームに喩えて、説明してみたい。
TDD の基本サイクル
TDDは、基本的に次のサイクルを小さく回していく。
-
Red
まだ通らないテストを書く。
次に実装する振る舞いを、失敗するテストとして明確にする。 -
Green
そのテストを通すための最小限の実装を書く。 -
Refactoring
テストが通っている状態を保ったまま、内部構造を整える。
このサイクルでは、テストは常に「今の振る舞いが壊れていないか」を確認する役割を持つ。
Redで攻める場所を決め、Greenで領地を取り、Refactoringで整備する。
そしてテストが、すでに取った領地を守る門番になる。
Red — 次に攻める場所を決める
まず失敗するテストを書く。
テストだけ書いて、実装はしない。
このステップでは、まだ実装できていない振る舞いを明確にする。
陣取りゲームでいえば、次にどこを取りに行くかを決めることにあたる。
敵陣を攻めるなら、自陣との境界を明確にする必要がある。
だからRedは「失敗」ではない。むしろ、攻める場所が見えている状態だ。
何を実装すべきかが曖昧なまま手を動かすのと、Redのテストという形で目標が固定されているのとでは、進み方がまるで違う。
Green — 領地を取る
次に、そのテストを通すための最小限の実装を書く。
たとえば sum(1, 1) のテストを書いた直後なら、最初は 2 を返すだけの実装でもよい。
これは最終的な実装ではなく、テストが本当に失敗から成功へ変わることを確認するための足場だ。
このようにすることで、「テスト自体が間違っていた」という可能性を薄くすることができる。
その後、別の入力例を追加しながら、一般化された実装へ近づけていき、Greenを都度確認する。
Greenは、その振る舞いが自分のコードの領地になったことを示す。
テストで表現された範囲については、コードが期待通りに動くことが確認できる。
ここで大事なのは、最初から美しい実装を目指さないことだ。
まずは領地を取る。汚くてもいい。整備はそのあとでいい。
占領が先、要塞化はあと、という順番を崩さない。
Refactoring — 取った領地を整備する
Greenになったら、そこで初めてリファクタリングする。取った領地を雑なまま放置すると、次が攻めにくくなる。
道は通っておらず、境界は曖昧で、どこに何があるのか分からない陣地からは、次の遠征に出られない。
自陣はしっかり整備しないと、クーデターが起きてしまうかもしれない。
だから重複を消し、責務を分け、名前を直す。次の変更が入りやすい形に整える。
Greenという足場があるから、安心して整備できる。
リファクタリングは「ただコードをきれいにする作業」ではなく、次のRedをGreenにしやすくするための地ならしだ。
テストは門番である
そしてこの整備フェーズで、テストは門番になる。
リファクタリングでは内部構造を自由に変えていい。だが、すでに取った領地を失ってはいけない。テストが落ちるということは、どこかの振る舞いを壊したということ。陣取りゲームでいえば、確保したはずの境界線が崩れた状態だ。
ただし、門番が守れるのは、あくまでテストとして表現された振る舞いだけだ。
書いていない境界条件や仕様の抜けまでは守ってくれない。
だからこそ、Redでは「次にどの振る舞いを領地にするか」を小さく、具体的に決める必要がある。
テストという門番が立っているからこそ、Greenの安全圏のなかでだけ、設計を大胆に動かせる。守りが保証されているから、攻めの形を自由に組み替えられる。これがTDDの一番おいしいところだと思う。
まとめ
TDDとは、テストで領地を少しずつ広げ、門番が守るGreenの安全圏で設計を耕していく開発手法だ。
Redで攻め先を決め、Greenで取り、Refactoringで地ならしする。
この三拍子を、門番つきで小さく回し続ける。
こうして適切なサイズでサイクルを回し、領地を広げ、目指していた実装という国を築き上げる。
一国一城の主を目指す道のり——それがTDDなのかもしれない。
T 殿様気分
D で
D Develop しよう
っちゅうわけやな。



