本記事は「「Work fun!」を体現する! Works Human Intelligence Advent Calendar 2025」の 22 日目の記事です。
21 日目は@_53aさんの3D プリンタを買ってしまった話でした。
生活の中で使えるものも自作できるのは素晴らしいですね!ちょっと前に分割キーボードを椅子に取り付けるマウントを 3D プリンタで作った方を見たこともあり、かなり憧れてます。
ちなみに私はブラックフライデーで念願のVICTORIA 製トルティーヤプレスを購入しました。タコスパーティーが捗りますね!
新人が TDD 本を読んでみた感想
さて本題ですが、ここしばらく Kent Beck の『テスト駆動開発』(和田卓人訳)1を読んでいました。新卒 1 年目で読む本としては背伸びしてるかも?と思いつつ、挑戦してみたら非常に良書で、多くの学びがありました。
読む前は「テストコードを先に書くなんて、二度手間で大変そう……」という先入観があったのですが、読み終わってみると「これはテストの話ではなく、設計と実装の進め方の話だ」という驚きがありました。
今回は、特に印象に残ったポイントをいくつか紹介したいと思います。
「写経」で歩幅をコントロールする感覚を掴む
読む上では、手を動かしながら進めることを徹底しました。
TDD の原則に「変更のステップをできるだけ小さくする」というものがありますが、本書はサンプルコードが非常に豊富です。コードを少しずつ変更していく流れが丁寧に実例として示されており、これを写経しながら進めることで、「これ以上小さくできないという単位まで分解して考える」感覚を体感できました。
個人差はあると思いますが、この「最小限の変更」というリズムは、実際にタイピングして「テストが通る喜び」を何度も味わわないと、なかなか腑に落ちない部分だと思います。
「品質」ではなく「設計」のためのテスト
TDD の基本的な流れは、いわゆる「レッド・グリーン・リファクタリング」です。
- 失敗するテストを書く (Red)
- テストを通すための最小限のコードを書く (Green)
- コードを綺麗に整える (Refactor)
「テストを書く」と聞くと、多くの人は「完成品が壊れていないか確認する作業」を想像するはずです。しかし TDD におけるテストは、いわゆる品質保証(QA)のためのテストではないのです。TDD によってテストが充実し、品質向上に繋がることは確かですが、それはあくまで副次的な効果であり、プロセスの結果として勝手についてくるものです。
TDD のテストは、「設計のためのテスト」です。つまり、「これから作るコードにどんな振る舞いをしてほしいか」を宣言することなのです。
TODO リストで思考を外部化する
実際にどのようにテストを書くのか、少し流れを追っていきます。
本書の第 Ⅰ 部では、以下のような要件の多通貨計算を行うコードを作ります。
-
通貨の異なる 2 つの金額を足し、換算された金額を得る
-
金額に数値を掛け、金額を得る
これを具体化して、次のような TODO リスト を作ります。
[ ] $5 + 10CHF = $10 (レートが2:1の場合)
[ ] $5 * 2 = $10
人間の脳のワーキングメモリは限られています。「実装しながら、次にやることを考える」のは負担が大きいです。TODO リストに書き出すことで、脳を「目の前の 1 行をパスさせること」だけに 100%集中させることができます。
この TODO リストを元に、1 つずつテストを書いていきます。(TODO リストの全てをいきなりテストにしない!)テストははじめは失敗しますが、次にこのテストを通すための最小限のコードを書きます。テストが通るようになったら、リファクタリングを行い、次の TODO に取り掛かります。
実装していくうちに、新しい TODO に気が付くはずです。その際はすぐにそちらに取り掛かるのではなく、一旦 TODO リストに書いておきます。そして現在取り組んでいたサイクルが終わった後に、改めて TODO リストを見直し、次に取り組むべきものを選びます。
このように、ここで作成したリスト、そしてリストから作成したテストコードは、「次に何に取り組むか?」を決めるロードマップになっているのです。
ここで重要なポイントは 3 つありました。
-
一歩ずつ進む
リストの中から「今から倒す敵」を 1 つだけ選び、そのためのテストを書く。 -
脱線しない
実装中に新しい課題に気づいたら、すぐに手を動かさず、一旦 TODO リストの末尾に書き足す。 -
ちょっとした割り込みを楽しむ
2 の例外。「ちょっとした」ものに限って割り込んでもいい。割り込みにさらに割り込むことはしない。
私のような新人エンジニアにとって、「あれもこれも同時にやって収拾がつかなくなる」というのはよくある失敗パターンではないかと思います。TDD の進め方はある意味シングルタスクを強制するため、こうした失敗を防ぐための強力なフレームワークになり得ると感じました。
リファクタリングが「本命」
本書を読み進めて意外だったのは、内容の 6 割以上がリファクタリングと、その指針となるデザインパターンや設計の解説に割かれている点です。(ちゃんと数えたわけではないので、体感です)
「テストが通ったら終わり」だと思っていた私にとって、これは衝撃でした。実は、TDD においてテストが通った直後の Green 状態は、まだスタートラインに立ったに過ぎないのです。
「動くコード」と「良い設計」を同時に求めない
人間の脳は「正しく動かすこと」と「美しく設計すること」を同時に処理するのが苦手です。
TDD は、この 2 つを明確なステップで切り分けます。
-
Red ~ Green: 「新しい機能」を最速で作る。設計の美しさよりも、まずは動くコードを書く(汚くてもいい!)。
-
Refactor: 重複を取り除き、設計を洗練させる。
「汚くてもいい」と自分に許可を出すことで、実装中のプレッシャーが劇的に減り、結果としてコーディングのスピードが上がります。
TDD ではリファクタリングすべき事項として具体的に「重複の排除」が挙げられています。ここで重複は単なる悪ではなく、「ここに共通の概念が隠れている」という設計のヒントになります。
例えば、プロダクトコードに同じようなロジックが 2 箇所以上現れた場合、それは「そのロジックを抽象化して共通化できる」というサインです。条件分岐が複雑になっていたら、Factory Method パターンを使って整理できるかもしれません。
リファクタリングのフェーズでこれらの重複を丁寧に取り除いていく過程こそが、まさに「設計を洗練させる作業」そのものです。TDD においてリファクタリングは余裕があったらやる掃除のようなものではなく、次の機能を実装するための不可欠な「地ならし」なのです。そしてこのとき、テストがあるからこそ、大胆にコードの構造を変える挑戦ができます。
- テストを書く。
- コンパイラを通す。
- テストを走らせ、失敗を確認する。
- テストを通す。
- 重複を排除する。
最初の 3 つのフェーズはなるべく速く通過して、新しい機能がどの状態にあるのかわかるところまで行きたい。そこにたどり着くためには、どのような罪を犯してもいい。その短い時間だけは、速度が設計よりも重要だからだ。
(中略)
最初の 4 つのステップは、5 つ目(重複を排除する)がなければ無意味だ。正しい設計を、正しいタイミングで行う。動かしてから、正しくする。
— Kent Beck, 『テスト駆動開発』 p.30(和田卓人 訳 / オーム社)
こうなると、TDD の実践のためには設計やデザインパターンの引き出しを多く持っていることが必要だと感じました。今後このあたりを勉強したいと思いました。
AI 時代の TDD は「仕様を定義する力」になるか?
これは本書に書いてあった内容ではなく、私の呟きなのですが…。
AI に「どう書くか(実装)」を任せられる現代において、人間が集中すべきは「何を作るか(設計・振る舞い)」にシフトしている…という類の話は、もうどこでも当たり前のように言われていることですよね。
TDD の進め方は、まさにこの「何を作るか」に集中するためのフレームワークとして機能するのではないかと感じています。
ただ、これはまだ「なんとなく相性がよさそう」レベルの感覚なので、教科書的な TDD の方法論が AI エージェントなどを利用した開発に本当に有効なのかは、色々試してみないとわからないなと思っています。
「AI に先にテストを全部書かせる」は TDD じゃない。でも、それもアリだよね。
最近こんな記事を見つけて、興味深く読みました。ここでは TDD の「よくある間違い」とされるテスト一括作成が、状況によっては有効である可能性が示唆されています。
AI の出力を客観的に評価する「ガードレール」をどのように設けるのがいいのか、これから考えていきたいです。
おわりに
Kent Beck の『テスト駆動開発』は、TDD の基本的な進め方を学ぶだけでなく、設計と実装の関係性について深く考えさせられる良書でした!TDD に興味がある方は、ぜひ手に取って手を動かして、体験してみることをお勧めします!
明日は@goatakaさんの投稿になります。お楽しみに!
