テスト駆動開発(TDD)は、アジャイル開発に非常に良く適した開発技法である。プログラムを書く前にテストケースを書くという、今までの開発のやり方とはまったく逆の「目的から解法を求める」やり方です。このやり方だと何がいいのかというと、目的が見えているから(テストケースを満足させること)、解法が非常にシンプルになることです。つまり無駄がなくなる。トヨタのカンバン方式をご存知ならば、ほとんど一緒の考え方がこのテスト駆動開発になるのです。
本書は、今までの開発方法とは一風変わったテスト駆動開発を、日本人による解説と豊富なサンプルプログラムで分かりやすく理解できます。なぜテスト駆動がいいのかということを、余すことなくかかれています。
開発者だけでなく管理者の方も、本書を読むことで品質の良いプログラムを作るためのきっかけが得られるのではないかと思います。とても良い本だと思うので、少しでもテスト駆動開発に興味のある方は読んでみてください。
解説
本書のタイトルに『バグがないプログラムの作り方』とあるので、プログラミング技法の本かと思いますが実は違います。
本書は、テスト駆動開発という開発手法の本となります。今までの開発は、「十分な設計 ⇒ 実装 ⇒ テスト」の順で行われているのが主だったと思います。が、テスト駆動開発だと、開発の流れが「必要最低限の設計 ⇒ テスト ⇒ 実装」の順になります。
実装の前にテストを行うのが、テスト駆動開発の特徴です。実装前にテストを行うことに意味があるのかというと、ここに非常に意味があります。品質のよいプログラムを書くためにはテストを最初に行う必要があります。
テスト駆動で開発すると良い事が、本書の中で非常に丁寧に分かりやすく、納得しやすく書いてあるので興味がわいてきたら読んでみてください。すらすら読めてしまうので、3時間もあればほとんど読めてしまうと思います。非常に良いことがかいてあります。
覚書き
リズムが大切
テスト駆動開発で重要な要素の一つして「リズム」があります。一般的にテスト駆動で開発するときにはJUnitを使っています。
このJUnitは、テストに成功すると「グリーン」、失敗すると「レッド」のバーが出力されます。
テスト駆動開発では、「レッド、グリーン、リファクタリング」というリズムを絶えず繰り返すことが、テスト駆動開発の極意となっています。最初にテストに失敗することからスタートします。ずっとグリーンだと、ほんとにプログラムがあっているのか不安になってきます。ですので、最初に「レッド」からスタートします。
グリーンにした後にリファクタリングを行うのがポイントで、最初のグリーンにする作業では、一番簡単なやり方(Fake It!)でテストをパスすることだけを考えます。次のリファクタリングフェーズで、重複をなくすようなコードに変更していきます。
テスト駆動で開発するときに、最初のレッドにする作業とグリーンにする作業が非常にかったるくなってくることがあります。でも、ここが我慢のしどころで、「レッド、グリーン、リファクタリング」のリズムを守ることを重視してください。折れそうになったら、「ペアプログラミング」をして、パートナーに何とか抑制してもらいましょう。
テストコードを書くときのポイント
- テストコードにはコードの意図を伝えるコメントを入れる
- テスト同士が関連するのは避ける
- テストの名前には何のテストをしているかと分かる名前を付ける
テストコードには、引数の意味や数字の意味などを書いておくべきです。テストコードにはリテラルがそのまま使われることが多々ありますので、後々見たときに数字の意味が分かるようにしておくようにします。
プログラムに修正が入る場合、テストコードから最初に修正します。また、テストコードより先にテストコードに書いたコメントを最初に修正します。
テスト駆動とDependency Injection
Dependency Injection(依存性注入)というものがあります。これは簡単に言うと、クラスの関連を実装と切り離しておいて、第三者によって実装を設定させるというものです。(あんまり上手く説明できてないな・・・) テスト駆動開発を行う上で、あるメソッドをテストするときにクラスの関連が多すぎてテストしにくい場合が出てきます。その場合、設計を見直して関連を減らすことが出来ればいいのですが、出来ない場合も出てきます。
そんな時、MockオブジェクトのほかにもDIを使うことでテストしやすくできます。
参考
「テスト可能」なアプリケーションにするための7つの原則
- 1. GUIビューの外側に
- GUIのビューからコードを切り離すことが出来れば、単純なメソッド呼び出しとしてコードをテスト出来るようになる。
- 2. 型によるエラー検査
- 型の検査はシステムが自動的に行ってくれます。高い抽象度で型を切り出すことは、ほとんどの場合よいことです。
- 3. 「断層線」を避けるために仲介機能(mediator)を利用する
- 独立したコンポーネント同士のインターフェースに仲介役を用意すると、公開メソッドの呼び出しのみを使ってコンポーネントをテストすることが簡単になります。
- 4. メソッド、小さなシグニチャーおよびデフォルトの引数
- 小さな引数や、シグネチャを持つメソッドが複数(オーバーライド)あるほうが、テスト時に簡単に呼び出せます。
- 5. アクセサーは、メモリー状態を修正してはいけない
- テストでオブジェクトの状態を検査するときには、オブジェクトの状態を変更しない用にするべきです。さもなければ、内部状態を検査しにくくなってしまいます。
- 6. インターフェースを使ってプログラム外のコンポーネントを明示する
- プログラム外のコンポーネント接続にはインターフェースを使うことで、すべてのコードがそろわなくてもテストすることが出来るようになります。
- 7. 最初にテストから考える
- 最初にテストから実装することで、実装段階で間違いを発見することが出来るようになります。
参考
参考
- テスト駆動開発といったらケントベックは外せません。
- JUnitに関することならこれがおすすめ
- テストファースト開発に関して分かりやすく解説しています。JUnitの使い方に関しても解説されています。