TDD
テストを先に書いてから実装するソフトウェア開発手法。設計と品質を同時に高める
TDD とは
TDD (Test-Driven Development、テスト駆動開発) は、実装より先にテストを書くソフトウェア開発手法だ。「まず満たすべき条件をテストとして書き、それを通すコードを書く」という順序を徹底する。考案者は Kent Beck で、著書『Test-Driven Development By Example』が原典にあたる (邦訳は 2003 年の『テスト駆動開発入門』ピアソン・エデュケーション、2017 年の新訳『テスト駆動開発』オーム社)。版元による同書の位置づけも、テスト自動化そのものではなく、ユニットテストとリファクタリングを両輪にした小さいサイクルで不確実性を抑え、設計を継続的に進化させる手法という説明になっている。
レッド・グリーン・リファクタリング
TDD は、短いサイクルを繰り返して進める。
| 段階 | 内容 |
|---|---|
| レッド | まず失敗するテストを書き、失敗を目で確認する |
| グリーン | テストを通す最小限のコードを書く |
| リファクタリング | 振る舞いを保ったままコードを整理する |
レッドで「失敗を確認する」工程を省かないことが要点だ。テスト自体が対象を正しく検査できているかを確かめられるのは、この一度だけである。条件の書き間違いで最初から通ってしまうテストは、以降ずっと緑を返し続け、何も守っていないのに守られている錯覚を残す。
グリーンの通し方には段階がある。原典では、期待値をそのまま返してまず緑にする仮実装、2 例目のテストを足して一般化を強制する三角測量、初めから正しい実装を書く明白な実装が、実装戦略として整理されている。自信のある処理は明白な実装で一気に書き、勝手が分からない処理は仮実装から入る、という使い分けになる。
サイクルを小さく保つ理由は、失敗したときに原因の範囲が直前に書いた数行へ限定されるからだ。まとめて書いてから通そうとすると、赤の原因が実装なのかテストなのか切り分けられず、デバッガで探す時間が戻ってくる。
なぜ設計が良くなるのか
テストを先に書くには、「このコードをどう使うか」を最初に決める必要がある。呼び出す側の視点から入るため、引数や戻り値の形が使う側の都合に寄り、責務の切れ目もはっきりしやすい。
逆向きの効果のほうが実務では大きい。テストから呼ぶには依存を外から差し込める形にせざるを得ないため、グローバルな状態を直接読むコードや、生成した瞬間に外部サービスへ接続するコードは、そのままではテストに載らない。テストの書きにくさが、設計の問題を実装の途中で知らせてくれる。TDD が単なるテスト手法ではなく設計を駆動する手法と言われるのは、この検出が早い段階で働くからだ。
向き合い方の注意点
TDD は強力だが、万能でも必須でもない。何を作るか定まらない試行錯誤の段階や、画面の見た目のように期待値を文章で書き下しにくい領域では、無理に適用するとかえって非効率になる。
もう一つの落とし穴は、実装の内部構造をそのまま写したテストを書いてしまうことだ。内部のメソッド呼び出し順序まで固定したテストは、構造を整えるたびに壊れる。リファクタリングを守るはずのテストがリファクタリングの足かせになり、やがてテストを消す判断に傾く。守る対象は公開された振る舞いに寄せる。
適用するかどうかの目安は、壊れたら困る振る舞いか、変更が繰り返し入る箇所かの二点で足りる。どちらでもない使い捨てのコードにまでサイクルを回す必要はない。
最初の一歩としては、既存コードへテストを後から足すより、次に直すバグの再現テストを 1 本書いてから直すのが早い。失敗するテストを先に見る感覚は、この順序でしか身につかない。
この記事は役に立ちましたか?
関連用語
関連する記事
テスト本ガイド - テスト設計を学べる技術書の選び方
テストの書き方からテスト戦略まで学べる技術書の選び方を紹介。テストピラミッド、TDD の正しい読み方、テストの ROI の考え方を解説します。
「動くコード」と「良いコード」の間にある本
コードが動くようになった後、次に何を学べばよいのか。「動くコード」を「良いコード」に変えるために必要な知識と、それを効率的に学べる本の選び方を解説します。
バグを生むのは知識不足ではなく想像力不足である
バグの多くは、コードを書いた時点で「こういうケースもありうる」と想像できなかったことが原因です。想像力を鍛える読書法と、エッジケースへの感度を高める方法を解説します。