ノート:テスト駆動開発

ページのコンテンツが他言語でサポートされていません。
  • テスト駆動開発は、きれいどころの外堀から攻略していく形式的な開発方法とは全く逆のアプローチであり、本能的に敬遠したくなるような開発の泥沼を、現状で頭をできるだけ使って先に進むことができると判断できる範囲で攻略していく実践的なものである。「写本」などと称して盲目的にテスト駆動開発の例を書き写すのは、つまり形式の観点からアプローチすることであり、テスト駆動開発の精神とは全く逆のことをしている。テスト駆動開発の例を生かすには、まず自分の頭で考えて泥沼に足を突っ込み、次に例を見てどのように著者は考えているか、どのようにそれを攻略しているか、その相違は何から生じているかを検討するのが有益だろう。
  • テスト駆動開発を行えば自動的にコードが生成されるなどというものではない。また、他の開発手法とコンフリクトするものではなく、むしろ補完する位置付けになるだろう。すなわち、テスト駆動開発においてそのテストを駆動させるのはTODOリストであるが、どのようにTODOリストの粒度をテスト可能なものまで砕いて追加していくかは、テスト駆動開発の範疇外である。それは、開発者の頭の中にこのソフトウェアの最終形・あるべき姿から生まれる意思・意図や、デザインパターンなどのソフトウェア開発に関する知識、開発対象のドメインに対する知識などによって補われるものである。また、元来、ソフトウェア開発はオーダーメイドで試行錯誤が前提であり、TODOリストに間違った方向性を与えたり後戻りしたりすることを躊躇しないこと。
  • テスト駆動開発の欠点として、テストコードの量が増えそのことで開発が遅くなることを挙げるものがいる。テスト駆動開発はあくまで開発手法であり、そのことで開発が遅くなるならばそれは何かが間違っている(汚いコードや動かないコードで十分であるなら話は別だが)。ソフトウェア開発者にとっては、コーディングのコストは低く、テスト駆動開発は頭で考える負荷を手に分散する手法である。難しいことを考えるときにノートにメモ書きするとき、メモ書きのコストを考えるだろうか(もちろん、コーディングのコストが無視できない人にとっては、外国語縛りのメモ書きのようなことになるが)。また、このメモ書きに相当するテストコードは、本コードと合わせて検討することで、開発者の主観によって(しかしある程度の能力者なら一定レベルのコンセンサスが自然とできるだろう)本コードの正しさへの信頼が獲得できるものに限定する。頭を使わずに単にケースを網羅するテストを書く形式的な作業は、テスト駆動開発の精神とは全く逆のものである。TODOリストから選ぶときも、それによってどのような結果になるかを頭を使うこと。テストに対する本コードの実装については、Fake Itが特異で目立つが、Obvious Implementationがほとんどを占めるべきである(すぐにコーディングできるのにわざわざFake Itをしてからリファクタリングするのは、頭を使わない形式的な作業である)。テスト駆動開発は、頭をできるだけ使うように仕向け、できるならその負荷を手にも分散するものであり、開発を加速する・減速しないために使われなくては開発方法としては意味が無い。
  • GUIの開発に対して、単体テストが作成しにくい・できないからテスト駆動開発は適用できない、ということに対し、様々なソフトウェア技術を駆使・導入すれば単体テストが作成できるからテスト駆動開発はできる、と主張するものがいる。まず、第1に、それは本当に開発を加速するのに用いているのか。第2に、テスト駆動開発は(Obvious Implementationが適用できなければ)Fake Itにて具象的な実装から始まり、徐々に抽象化し主ロジックを見つける方法を取るが、これに反して、テストを作るためにいきなりソフトウェア技術を駆使・導入するのは(形式先行でもあり)テスト駆動開発の精神に逆行する。自動化できる単体テストでなければテスト駆動開発にならないということではない。実際、ケントベックのTEST-DRIVEN DEVELOPMENT BY EXAMPLEのパート2では、テストフレームワークを作るのに、最初の方は人の目でテストの合否を確認している。後の方で、これをテストフレームワーク自身に確認できるようなものにしているのだが、これは、テスト駆動によって出来るものではなく、リファクタリングによって出来るものである(それはそれで価値があるが、テスト駆動で出来たテストではない)。また、最初は、テスト駆動開発に不慣れな人なら思いも付かないような簡単なテスト(フラグの確認)から始まり、徐々に抽象化を行っていることをは目を引く。必要最小限の抽象化・複雑さは自明ではなく、それが得られるのはテスト駆動開発の利点の一つである。GUIの開発に目を向ければ、そこに、テスト駆動開発の精神を反映させるなら、最初にどのようなGUIを作るかを考え、(Obvious Implementationが適用できなければ)Fake ItにてハードコーディングにてGUIを作り、(GUIを何度も確認しながら)主ロジックを抽出するリファクタリングをするのが初手であろう。ここからソフトウェア技術を駆使・導入して自動化可能な単体テストに変化させていくのは(有用かもしれないが)それはテスト駆動で出来るテストではなく、リファクタリングによって出来るものである。

--思案猫 2011年2月4日 (金) 19:03 (UTC)[返信]

  • テスト駆動開発のテストは仕様とは直接的な関係はない。もちろん、TODOリストの出発点として仕様を使うのは自然と思われるし、仕様がそのままテストに落とせるような簡単なものなら、(TODOリストを経由して)それぞれの仕様に対応したテストを作って実装していくのが楽だろうし、あえて無駄に労力を掛けるまでもない。しかし、逆に言えば、それは、対象とする問題が簡単すぎて、あるいは、既に何らかの設計手法によって仕様がテスト可能なレベルまで細かく砕かれていて、テストを書くことが頭を使う必要のない形式的な儀式になり下がっているということである。TDDのテストは仕様であるという主張や、TDDでは前もって詳細な設計・仕様が必要だという主張は、TDDは仕様から設計を編み出していくための駆動点として使うという重要な側面を理解していない。

--思案猫 2011年6月14日 (火) 11:23 (UTC)[返信]