テスト駆動開発

テスト駆動開発 (てすとくどうかいはつ、; TDD) とは、プログラム開発手法の一種で、プログラムに必要な各機能について、最初にテストを書き（これをテストファーストと言う）、そのテストが動作する必要最低限な実装をとりあえず行なった後、コードを洗練させる、という短い工程を繰り返すスタイルである。多くのアジャイルソフトウェア開発手法、例えばエクストリーム・プログラミングにおいて強く推奨されている。はビヘイビア駆動開発へと発展を遂げている。
開発サイクル.
最も基本となる開発サイクルは以下のようになる。
なお、テストの実行環境ツールであるxUnitでは、テストの失敗を赤いバー、成功を緑のバーで通知するため、上記のサイクルは Red/Green/Refactor と称される。
より実践的には、to-doリストを組み合わせることにより、以下のような手順で開発する。
テストコードは、最初から自明であるとは限らない。むしろ、コード本体と同様、最初は具象的なテスト（例えば、単なるフラグの確認）を行ない、これによって知見を得た後に、テストを書き直したほうがよい。また、テストコードから導かれるコード本体は、リファクタリングの過程によって、あるいはテストが成熟するに従って、最終的な目的とするコード本体のテスト用スタブに変わっていくかもしれない。早い段階でテストとコード本体を分離して管理するのはあまり意味がない。テストやコード本体が成熟していくにつれ、テストの記述が抽象的・間接的になり、リスクが導入される（例えば、フィールドを直接参照する代わりにgetterメソッドを使うなど）。しかし、テスト駆動開発のテストの目的は、開発者の正しさへの確信を裏づけするためであり、それが保たれているならば問題はない。
テスト駆動開発で用いられるテストは、品質のためのテストではない。したがって、コード本体とは独立してあらゆるケースを網羅するテスト、すなわち「テストそのものが価値を持つようなテスト」を目指しているわけではない。テスト駆動開発におけるテストとは、コード本体とテストを合わせて検討することで、開発者がその正しさに確信を得るようなものである。したがって、開発者の確信に少しも寄与しないテスト（また、ドキュメントとしてテストの読者に何かを伝えるために書かれていないもの）は、むしろ積極的に削除を検討する。
テスト駆動開発を実施するには、テストを自動的に実行できる環境が必要である。そのような環境としては、JUnitやNUnitといったもの（総称してxUnitとされる）が挙げられる。なお、このテスト実行環境は、コンセプトが単純であり、かつ非常に強力であることから、実行環境そのものをテスト駆動開発で自作するのもよい。ただし、そのテストツールをテストするツールはないことから、しばらくは慎重な人の判断でもってテストの代わりとすることになる。
適用の注意.
テスト駆動開発に適合させるのが難しいものに、以下のものが挙げられる。
前者は、盲目的にその良し悪しが判断できない（人の判断が必要である）ためである。後者は、実行環境におけるマルチタスク・マルチスレッドの動作による非決定論的な要素が絡み、再現性に問題があることから、やはり盲目的に良し悪しを判断できないためである。不具合がないことが前提とされているため、その点に関しては、テスト駆動開発を導入することで、一定の効果はある。
また、以下のものについても、テスト駆動開発が難しいとの指摘がある (Darach's Challenge)。
その他にも、既に構築してあるコードに対して、テスト駆動開発を導入するのも難しい。なぜなら、それらのコードはテストがしやすいようには作られていないことが多いため、先にリファクタリングをする必要があるが、リファクタリングを行なうにはその動作の保証をするためのテストが必要だからである。これはある種のデッドロックやジレンマを生み出す。また、やってはいけないことは、片っ端からテストを書いたり、リファクタリングを行なったりすることである。変更する範囲を制限することを決心し、何らかのフィードバックを得ることを前提としてコードを変更していくことが必要である。