いろいろ腑に落ちない。
テストファーストのユニットテストは、中間的オブジェクトや間接的で過剰に複雑な構造を生みがちだ。「遅い」ものをすべて避けようとするのがその理由で、データベースやファイルIOなどを避ける。ブラウザを使ってシステム全体をテストするのも避けようとする。結果として、本当に恐ろしく巨大なアーキテクチャが生まれてしまう。
テストファーストでなければ、ユニットテストは複雑な構造を生まないのだろうか。先に書こうが後で書こうが、遅いものをすべて避けようとすれば、ユニットテストは複雑な構造を生むだろう。TDDは無関係ではないか。
また、DHHは「すべての依存関係をモックにし、何千というテストが数秒で終わるようなユニットテスト」は「Railsアプリケーションのテスティングにおいてはいいやり方ではない」というが、その根拠がよく分からない。
ぼく自身は、複雑な構造を避けたいなら、そういう構造を要請するユニットテストを排するしかないと思う。そのかわり、システムテストを重視すればよい。その点においては、DHHの意見に賛同できる。
だが、DHHは「システムテストがすべてだ!」といった極論には与しないという。どうしたらよいのか。
DHHの挙げている参考文献(Why Most Unit Testing is Waste by James Coplien)では、どんなときにユニットテストを書くべきで、どんなときにシステムテストを書くべきか議論されている。
- Keep regression tests around for up to a year — but most of those will be system-level tests rather than unit tests.
- Keep unit tests that test key algorithms for which there is a broad, formal, independent oracle of correctness, and for which there is ascribable business value.
- Except for the preceding case, if X has business value and you can text X with either a system test or a unit test, use a system test — context is everything.
"In most businesses, the only tests that have business value are those that are derived from business requirements. Most unit tests are derived from programmers' fantasies about how the function should work; that has no provable value." だって。