最初に
テスト駆動開発(以後TDD)の存在を知って、自分で取り入れてみてから、自分の開発は良くなったと思っています。
TDDを人におすすめしよう! と思って本を読んだり色々と調べていたりするうちに、
TDDは死んだ とか、テスト全部書かなくても...と言われていることを知りました。
それでも自分はTDDで開発するのが好きだし、自分には合っていると思うので、自分がTDDを愛する理由を書いてみたのがこの記事です。
若干ポエム寄りになっているかもしれませんが、ご容赦いただけると幸いです。
前提としていること
- TDDの基本的な流れとして、タスク細分化→Red/Green/Refactoringのループを回す、であること
- 実践者は初心者であり、実装にまだ不慣れであること(内容についての言い訳ではなく、そういう人がTDDを実践した事で感じた事を書いたという意味)
- TDDではなく自動テストによる恩恵も含む。TDDを実践すれば自動テストの恩恵を受ける事ができるから。
TDDを愛する理由たち
1.目の前のタスクに集中するリズムを作ってくれる
解決すべき問題
プログラマーが仕様書を受け取った時点で、詳細設計まで網羅されている事はあまりないと考えています。
必ず、ある程度ざっくりと決まった仕様から、コードを書ける程度のToDoに分解せねばなりません。
まずどこまで分解すればコードを書きやすくなるのか、初心者にはこの時点でハードルがあります。
また首尾よくタスクを分解できても、今度は複数のタスクが見えていることで、同時に複数の事が気になってしまい、生産性が下がってしまいます。
TDDによる解決
TDDではテストを書くと言われていますが、それより前にまず、仕様をざっくりToDoリストに落とし込みます。
その後に、よく知られているようなRed/Green/Refactoringが始まります。
これによって、上記の問題2つが解決されます。
まずどこまで分解すればコードを書きやすくなるのか、初心者にはこの時点でハードルがあります。
テストケースが書きやすくなるまで分解します。シンプルです。
今度は複数のタスクが見えていることで、同時に複数の事が気になってしまい、生産性が下がってしまいます。
Red/Green/Refactoringの各ステージで、もし行き詰まった場合に修正すべき対象は何なのか? が明白です。
同時に考える問題は、(初心者でなくとも)少ないほうが良いに決まっています。TDDのリズムは、目の前の事に集中する補助線となってくれます。
2.安心と共に修正できる
解決すべき問題
レビューを受けると多くの修正すべき問題点を指摘されます。
レビュー体制が整っている事は喜ばしい事である反面、沢山の指摘事項に怯む事もよくあります。
そして指摘事項を修正している間に、問題なく動いていたコードが破壊されていない保証はありません。
TDDによる解決
自動テストがあれば、既存コードを破壊してしまう可能性は大きく減じられます。
また、テストコードを書きやすいようにToDoが細分化されているので、どのToDoにおいて問題があったのかが分かりやすくなります。
3.設計の問題に早期に気付く事ができ、手戻りが減る
解決すべき問題
私が現在最も苦労しているのは、コードの詳細設計です。
どのように処理を分割すべきか? 分割した処理はどこに書くべきか? そういった概念は現在進行系で勉強している所です。
設計の問題において最も苦しい事は、設計に問題があっても、プロダクションコードだけ書いている間はなかなか気付かないという事です。
問題に気付けなければ相談しに行くこともできず、結果としてレビューの段階で大きく手を入れざるをえなくなります。
TDDによる解決
TDDは、特に設計になにか問題が起こると、**テストが書き辛くなります。**これが設計を見直す指標になります。
ToDoが大きすぎたり、特定の実装に依存し過ぎていたりすると、どうしてもテストが綺麗に書けません。
こうした時には実装の手を止めて、実装方法を相談しに行くようにしています。
4.歩幅を調節しながら進んでいける
解決すべき問題
TDDを批判する言葉の中に、「そんなに細かい粒度でテストを書く必要は無い」というものがあります。
具体的にその現場を見たわけではありませんが、その批判は的を射ているのかもしれません。
ベテランプログラマーでなくとも、「このToDoくらいはテスト書かずとも良いな...」と思う事もあります。
TDDによる解決
TDDには「歩幅の調節」という言葉があります。TDDは小さなToDoでテストを書いていく事を推奨はしていますが、必須ではありません。
Kent Beckの「テスト駆動開発」の中で、テストしなくてよいものはあるか という問いが投げ掛けられています。
シンプルに答えるなら、本書レビュアーのPhlipが言うところの「不安が退屈に変わるまでテストを書く」となる。これは一種のフィードバックループだ。ということは、答えは皆さん自身で見つけなければならない。
KentBeck. テスト駆動開発 (Japanese Edition) (Kindle の位置No.4559-4561). Kindle 版.
既に十二分に熟知している場所においては、少なくとも個人の不安を解消するためのテストコードは不要です。
うちではTDDを実践しているから、必ず最初にテストを書いてね という現場がもしあれば、それはTDDを実践しているとは言えないとすら思います。
5.(他の開発手法に比べて)比較的すぐに実践できる、すぐに効果を発揮する
解決すべき問題
プログラマーがコードを洗練させていく方法はTDDだけではありません。
動く綺麗なコードを生み出すために、DDDだったり、Clean Architectureだったり、他の勉強をすることも良いでしょう。
しかしそれらの勉強が生きるまでに、あるいは普段のコードに馴染むまでには、ある程度時間が掛かります。
TDDによる解決
テストを書くことが楽だとは言いません。 むしろテストを書くのは大変です。
モック作成のような、プロダクションコードを書く上では必要の無い知識を身につける必要もあります。
しかしTDDの導入自体は明日からやってみる事は可能です。
そしてその恩恵は、意外なほどすぐに現れます。
最後に
私がTDDを取り入れてみて、感じている恩恵についてまとめました。
まだまだ勉強すべきことは多いながら、TDDが死んだと言われるのは寂しい気持ちがあってこの記事を書くに至りました。
これから実践を重ねた結果、いつか私もTDDを放り投げるかもしれません。
しかしそういう日が来ても、TDDを勉強、実践する事で得たものは今後糧になっていくと思っています。