TDD(テスト駆動開発)はテストを優先してプログラム実装をすすめるソフトウェア開発手法です。テスト駆動開発を採用することにより、早期にバグを発見できる上に、必要な機能を無駄なく開発できるようになります。

ただ「テストを優先するとはどういうことか」、初めて学ぶ方にはイメージしづらいのではないでしょうか。テスト駆動開発には独自の方法論があり、単に「テスト・ファースト」な開発手法というわけでもありません。この記事ではテスト駆動開発の概要や方法論、メリット・デメリットについて解説します。

TDD(テスト駆動開発)とは

TDD(テスト駆動開発)とは最初にテストコードを記述し、そのテストを通過するようプログラム本体を実装していくソフトウェア開発手法です。テスト駆動開発ではこの手順で、最低限必要な機能から少しずつ開発をすすめ、機能を徐々に追加していきます。

このように機能を蓄積していく設計方法を「インクリメンタルな設計」と呼びます。テスト駆動開発は、インクリメンタルな設計に適した開発手法です。インクリメンタルな設計を採用すれば、できるだけ開発の無駄を減らし価値のある機能を徐々に蓄積できます。

なおテスト駆動開発は「テスト」という言葉が使われていることから、テスト手法の1つと誤解されます。しかし実際には、インクリメンタルな設計を促す開発手法であり、テストの方法論を表す用語ではありません。

【補足】
昨今では機能ごとの小さな単位で開発をすすめる「アジャイル開発」が注目されています。テスト駆動開発は、アジャイル開発を実現するのに適した手法として推奨されています。

アジャイル開発におけるテストとは?進め方と特徴を解説

テスト・ファーストとの違い

テスト・ファーストとは、プログラム実装の前にテストコードを作って実行する手法を指します。テストコードを先に作るという点では、テスト・ファーストとテスト駆動開発は同じです。

その上でテスト・ファーストとは、最初にテストを行いその後にプログラムの実装を開始するというテストの方法論です。一方のテスト駆動開発は、テストコードを作成したあとの手順にルールがあります。

テスト駆動開発では次に、そのテストを通過するためのコードを記述し、そのあとに作成したコードを整理し簡潔にします。テスト駆動開発はこの一連の手順を繰り返すことで、プログラムの設計や実装をすすめるソフトウェア開発手法です。

TDD(テスト駆動開発)のツール

テスト駆動開発を行うのに必要とされるのが「xUnit」と呼ばれるテスティングフレームワークです。より厳密に言うと、テスティングフレームワークには「PHPUnit」「NUnit」のように、「Unit」の頭に文字がついた種類が数多く存在します。

xUnitは、これらテスティングフレームワークの総称です。xUnitのテスティングフレームワークを活用することで、テスト駆動開発を効率的にすすめられるようになります。

TDD(テスト駆動開発)の開発サイクル

テスト駆動開発ではテストコードを作成してから、プログラムを実装するまで決まった開発サイクルを繰り返します。ここでは、テスト駆動開発の開発サイクルを1つずつ解説します。

TDDの開発サイクル

失敗(RED)

テスト駆動開発では最初にテストコードを記述します。プログラムが一切実装されていない状態でテストコードが実行されるので、このテストは必ず失敗します。この手順を「RED」と呼ぶのは、テストツールで失敗が確認された際に、赤色(RED)のバーでエラー表示されるためです。

成功(GREEN)

次にテストを通過するのに必要最低限なだけのコードを記述します。これによってテストに通過し、テストツールには成功を示す緑(GREEN)のバーが表示されます。

ここで重要なのは、この時点では完全なコードを記述することが求められていないという点です。テストを通過するのに最低限必要なコードの記述までにとどめます。

これは、少しずつ開発をすすめ機能を積み上げていくためです。開発サイクルを繰り返すことによって、段階的に全体のプログラムを完成させていくことが求められます。

リファクタリング(REFACTOR)

リファクタリング(REFACTOR)とは、外部からみたプログラムの動作を変えずに、ソースコードの内部構造を整理しきれいにすることです。テスト駆動開発では、テストに通過する最低限のコードが書かれた段階でリファクタリングを行います。

プログラムの規模が大きくなった状態でリファクタリングを行うと、コードを修正し整理する手間も大きくなってしまうからです。そうならないように少しずつ実装を進めていくのがテスト駆動開発の特徴です。

TDD(テスト駆動開発)のメリット

それでは、他の開発手法と比べテスト駆動開発にはどのようなメリットがあるのでしょうか。1つずつみていきましょう。

早い段階でバグを検知・修正できる

テスト駆動開発のメリットとしてまずあげられるのが、バグを早期に発見できる点です。プログラムの規模が小さい段階からこまめにテストを繰り返すことから、バグを検知・修正しやすくなります。

仮にバグが見つかっても、早い段階で発見されているため修正の負担も大きくありません。ずっと後でバグが発見されると、後戻りが必要となる分だけ修正の負担が膨大化してしまいます。

システムの要件や仕様を深く理解できる

テストコードを作成するためには、システムの要件や仕様を詳しく把握しなくてはなりません。テスト駆動開発では、機能を少しずつ追加する過程でテストコード作成やテストを繰り返すので、システムへの理解を深めやすくなります。

開発者の不安を軽減できる

テスト駆動開発では、テストを繰り返しつつ最低限の機能から着実に開発をすすめます。そのため仮にあとで仕様変更やバグ修正の必要が生じても、テスト結果の蓄積もあり対応すべき内容を整理しやすくなります。

これにより膨大な修正の負担が生じたり、プログラムの修正によって新たなバグが生まれたりするのを予防可能です。開発者に大きな負荷がかかりにくくなるので、心理的な不安も軽減されます。

無駄なく価値があるプログラムを実装できる

テスト駆動開発では、最低限必要な機能から少しずつ実装をすすめます。これによって「インクリメンタルな設計」を実現し、本当に必要で価値の高い機能を無駄なく開発しやすくなります。

TDD(テスト駆動開発)のデメリット

テスト駆動開発は、説明したようにメリットの多い開発手法です。しかし、その反面デメリットもあり、採用する際には十分に注意が必要となります。ここでは、テスト駆動開発の主なデメリットを紹介します。

開発にかかるコストが大きくなりやすい

テスト駆動開発では、プログラム本体のコードはもちろんのこと、テストコードも同様に保守・管理しなくてはなりません。仮に大きな仕様変更が生じた場合、テストコードを修正する負担も大きくなります。そのためテストコードを管理するためのコストが大きくなりやすいというデメリットがあります。

またテスト駆動開発により開発者がテストを行ったからといって、他のテストが必要なくなるわけではありません。たとえばユーザー向けのインターフェイスがあるプログラムでは、インターフェイスからも同様のテストを改めて行う必要があるのです。二重のテストを行う必要が生じることから、その分コストも増える傾向にあります。

慣れが必要となる

既存の手法からテスト駆動開発に切り替えるには慣れが必要です。初めてであれば、テストコードを記述しながら開発するのに時間もかかります。テスト駆動開発を導入した初期の段階では、これら課題を解決する必要があることを覚えておかないといけません。

まとめ

テスト駆動開発では最初にテストコードを記述し、そのテストに最低限通過するようコードを書きます。そのあとリファクタリングを行ってコードのシンプル化をはかります。

テスト駆動開発はこの手順を繰り返し、少しずつ必要な機能を積み重ねていくのが特徴です。テスト駆動開発を採用することによってバグを早期に発見し、必要な機能を無駄なくつくることができます。一方で、テストコードの管理にコストがかかったり、テストを二重に行う必要があったりといったデメリットもあります。

テスト駆動開発を採用する際は、これらメリット・デメリットをふまえ、自社の開発に適しているか検討することが必要です。