プログラマーとして、私はTDDの哲学に真摯に取り組み、自分が書いた重要なコードに対して広範な単体テストを行うように努力してきました。この道は時々苦痛になることがあります(複数の単体テストの変更をカスケードする原因となる動作の変更、大量の足場が必要です)が、全体として、変更のたびに実行できるテストなしでプログラミングすることを拒否し、コードのバグははるかに少なくなります結果。
最近、私はHaskellで遊んでいます、そしてそれは常駐テストライブラリ、QuickCheckです。TDDとは明らかに異なる方法で、QuickCheckは、コードの不変条件、つまり、入力のすべて(または実質的なサブセット)を保持する特定のプロパティのテストに重点を置いています。簡単な例:安定ソートアルゴリズムは、2回実行した場合でも同じ答えが得られ、出力が増加し、入力の順列である必要があります。次に、QuickCheckは、これらの不変条件をテストするためにさまざまなランダムデータを生成します。
少なくとも純粋関数(つまり、副作用のない関数-そして正しくモックを作成すればダーティ関数を純粋関数に変換できる)の場合、不変テストはそれらの機能の厳密なスーパーセットとして単体テストに取って代わる可能性があるように思われます。各単体テストは、入力と出力で構成されます(命令型プログラミング言語では、「出力」は関数の戻りだけでなく、変更された状態でもありますが、これはカプセル化できます)。おそらく、手動で作成したすべての単体テスト入力をカバーするのに十分なランダム入力ジェネレーターを作成することができます(そして、それはあなたが考えもしなかったケースを生成するので、いくつか)。境界条件が原因でプログラムにバグが見つかった場合は、ランダム入力ジェネレーターを改善して、そのケースも生成するようにします。
したがって、課題は、すべての問題に対して有用な不変量を定式化できるかどうかです。私はそれがそうだと思います:最初に答えを計算するよりも、それが正しいかどうかを確認するための答えが得られたら、それははるかに簡単です。不変条件について考えることは、アドホックテストケースよりもはるかに優れた複雑なアルゴリズムの仕様を明確にするのにも役立ちます。これにより、問題のケースバイケースの考え方が促進されます。以前のバージョンのプログラムをモデルの実装として使用することも、別の言語のプログラムのバージョンを使用することもできます。最終的には、入力または出力を明示的にコーディングしなくても、以前のすべてのテストケースをカバーできるようになります。
私は気が狂ったのですか、それとも何かに取り組んでいますか?