単体テスト
もっとも簡単なプログラムでさえも、すべての実行パスを評価するわけではないので、テストでプログラムのエラーが全てわかるわけではない。同じことは、単体テストにも当てはまる。さらに、単体テストは、その定義からユニットのみの機能自体をテストする。したがって、統合エラーや、より広範なシステムレベルのエラー(例えば性能など、複数のユニットにまたがって実行される機能や非機能テスト領域)を捉えることはできない。単体テストは、特定のエラーの存在や不在を示すだけで、エラーが無いことの証明にはならないから、他のソフトウェアテスト活動と合わせて実施しなければならない。 各実行パスの正しい挙動を保証するため、エラーの不在を確認するため、他のテクニックが必要となる、すなわち、ソフトウェアコンポーネントが期待されない挙動を示さないことを証明する正式なメソッドのアプリケーションが必要となる。
ソフトウェアテストは、組み合わせ問題である。たとえば、2分する判定ステートメントは少なくとも2つのテストが必要である。すなわち、結果が真となる場合と、偽となる場合である。結果として、多くの場合、作成コードの1行あたり、プログラマは3から5行のテストコードを書かなければならない。これは明らかに時間がかかり、その手間を投資する価値はないかもしれない。例えば、非決定的あるいは複数スレッドが関係する場合、テストは容易ではない。また、単体テスト用のコードには、少なくともテスト対象コードと同じくらいのバグが存在する可能性がある。フレッド・ブルックスは著書『人月の神話』で「船に乗るときは、クロノメーターを2つ持って行ってはならない。常に1個か3個を持っていけ。」と引用している。その意味は、2個のクロノメーターが矛盾する場合、どちらが正しいのか分からないから、ということである。
あるクラスは 他のクラスを参照しているため、あるクラスのテストはしばしば別のクラスのテストに影響してしまう。この一般的な例は、データベースに依存しているクラスである。クラスをテストするために、テスターは、しばしばデータベースと対話するコードを書く。これは間違いである。なぜなら単体テストは自分のクラスの境界を超えるべきではないし、特にそのようなプロセス/ネットワーク境界を超えることは許されない。その理由は単体テストスイートで受け入れがたい性能問題が起こりうるからである。また、そのように単体テストの境界を超えることは統合テストになり、テストが失敗したときに、そのコンポーネントが失敗の原因かどうかが分からなくなってしまう。フェイク、モック、統合テストを参照のこと。
その代わりに、ソフトウェア開発者は、データベースクエリの周りに抽象的なインタフェースを作成し、専用のインタフェースを持つモックオブジェクトを実装する必要がある。この必要な付属物をコード(ネットで有効な結合)から抽象化し、独立したユニットは以前よりも徹底的にテストすることができる。この結果、高品質でかつ保守性があるユニットができあがる。
コンピュータプログラミングにおいて単体テスト(たんたいテスト)あるいはユニットテスト(英語: unit test)とは、ソースコードの個々のユニット、すなわち、1つ以上のコンピュータプログラムモジュールが使用に適しているかどうかを決定するために、関連する制御データ、使用手順、操作手順とともにテストする手法である。ユニットとはアプリケーションのテスト可能な最小の部品単位である、と直観的にとらえることができる。手続き型プログラミングでは、ユニットは、モジュール全体のこともあるが、より一般的には、個々の関数や手続きである。オブジェクト指向プログラミングでは、ユニットは、クラスなどのインタフェース全体だが、個々のメソッドであることもある。単体テストは開発プロセス中にプログラマー、時にはホワイトボックステスターによって作成される。
理想的には、各テストケースは他から独立しているべきである。メソッドスタブ、モックオブジェクト、フェイク、テストハーネスなどのような代替を、モジュールを分離した状態のテストを支援するために使用できる。一般的に単体テストは、コードが設計通りであることと、意図したとおりに動作することを確認するため、ソフトウェア開発者の手によって書かれ、実行される。その実装は手作業(鉛筆と紙)からビルド自動化の一環として定式化される場合まで、さまざまである。
現在では、単体テストはxUnitといったテスト自動化ツールを用いて行われるのが主流となっており、単体テストを自動化されたテストとして言及するケースもある(本項目も、自動化されたテストとしての記述を含む)。しかし、単体テストはあくまでテストの粒度に対する分類であり、必ずしもテスト自動化を意味しないため、注意が必要である。
エクストリームプログラミングというのは、テストが(しばしば高価すぎて時間がかかり経済的に実施可能でないため)、いかにして効果的に限られた資源を集中するかについて基本的な考え方を示している。
重要なのは、テストコードは、重複を全て取り払い実装コードと同じ品質に維持されている点で、第一級のプロジェクト成果物であるという考えである。開発者は、テスト対象コードと対でコードリポジトリに単体テストコードを公開する。エクストリームプログラミングの徹底した単体テストの利点は、上記で述べたように、より簡単で、より自信があるコード開発とリファクタリング、コード統合の容易化、正確なドキュメンテーション、モジュール化の高い設計である。これらの単体テストはまた、回帰テストとして頻繁に実行される。
単体テストはまた、 創発的設計の概念の重要な要素である。創発的設計はリファクタリングに大きく依存しているので、単体テストもまた不可欠な要素である。