テスト駆動開発
実装に関する決定のフィードバックは、テストの失敗や通過によって通知される。両者とも、採用の決定から短い間隔でフィードバックを得ることができる。
テスト駆動開発は、あくまで開発のための手法であり、そこで得られるテストは副産物である。しかし、その開発手順から、コード本体は、テストをパスさせるために記述されたものである。そのため、理想的なテスト駆動であれば、カバレージは100%になる。欠陥やバグは、非常に少ないことが期待される。
過度な抽象化はむしろ柔軟性を失わせ、保守のコストもかかる。そこで、具象的なコードから始めて、次第にそれを抽象化していくことで、適切な抽象度で抑えることができる。つまり、現在の仕様に対応できるだけのシンプルさを保つことで、逆説的に将来の仕様変更への対応が容易になるのである。
テスト駆動開発に適合させるのが難しいものに、以下のものが挙げられる。
セキュリティソフトウェア
並列処理・並行処理
前者は、盲目的にその良し悪しが判断できない(人の判断が必要である)ためである。後者は、実行環境におけるマルチタスク・マルチスレッドの動作による非決定論的な要素が絡み、再現性に問題があることから、やはり盲目的に良し悪しを判断できないためである。不具合がないことが前提とされているため、その点に関しては、テスト駆動開発を導入することで、一定の効果はある。
また、以下のものについても、テスト駆動開発が難しいとの指摘がある (Darach's Challenge)。
グラフィカルユーザーインターフェイス (GUI) を扱うもの
分散オブジェクト
データベーススキーマ
サードパーティコードや、外部ツールで自動生成されるコード
その他にも、既に構築してあるコードに対して、テスト駆動開発を導入するのも難しい。なぜなら、それらのコードはテストがしやすいようには作られていないことが多いため、先にリファクタリングをする必要があるが、リファクタリングを行なうにはその動作の保証をするためのテストが必要だからである。これはある種のデッドロックやジレンマを生み出す。また、やってはいけないことは、片っ端からテストを書いたり、リファクタリングを行なったりすることである。変更する範囲を制限することを決心し、何らかのフィードバックを得ることを前提としてコードを変更していくことが必要である。