設計という意味でのテストコード
「変化に強い」に加えて、もう一つテストコードを書く理由があります。それは、「設計を良くするためにテストを書く」ということです。
テスト可能な粒度でのメソッド設計
メソッドに対してテストを書こうとした場合に、必ず考慮に入れなければならないことがあります。それは「テストが可能な粒度かどうか」です。例えば、テストしようとしたメソッドが500行あり、if文が30回出てきたとすると、そのパターンすべてをテストコードで表現しなければなりません。そもそも、テストを行う以前に500行あるメソッドは、責務がはっきりしない上に可読性も悪く、良い設計になっているとは言えないでしょう。
テストコードを書くためには、そのような良くない設計を見直さざるを得なくなります。メソッドをシンプルにし、可能な限り機能も行数少なくすることで、テストもシンプルになります。シンプルなメソッドを目指すと、全体設計としてもシンプルにかつ分かりやすくする必要が出てきます。
結果的に、テスト可能なメソッド設計にするということは、全体的に良い影響を与え、全体設計が良くなっていきます。
メソッドの動作設計という意味でのテスト駆動開発
テスト駆動開発(TDD)とは、まず最低限必要な機能のテストコードを書き、書いたテストが動作するプロダクトコードを書きながらさらに「テストコード→プロダクトコードを書く」いうサイクルを回しながら開発する方法です。手順は以下のとおりです。
- まず最低限必要な機能のテストコードを書く
- テストが失敗(レッド)することを確認する
- プロダクトコードを書く
- テストが成功(グリーン)することを確認する
- リファクタリング(設計の見直し、改善)をする
この方法が意味しているのは、「まず想定している動作をテストコードで書く」ことです。これは、例えば設計書を作るときに考えていることと同じであり「設計をしている」ということです。つまり、テスト駆動開発は、メソッドの動作設計をしながら実装を行うことを意味します。
テストの実行結果からフィードバックを得ることにより、リファクタリングを行いながらさらにプロダクトコードを高め、次の仕様のテストを書き、プロダクトコードを書く。このフィードバックサイクルを回しながら、メソッドの設計をしていくことにより、設計品質を上げながら、さらにテストコードによってその時点でのメソッドの品質を担保できます。
自動ビルドと組み合わせよう
記述したテストコードとビルドを組み合わせるとさらに効果が上がります。例えばgitでpushしたソースコードが自動的にサーバ上でビルドされ、すべてのテストコードが動作します。そうすることにより、チームの誰かが修正したものが、その他の人が修正したものと統合し、その影響範囲も含めて確認することができます。もし、エラーになったらメールなどで知らせることにより、すぐに対処ができるということも利点です。
このように一日に何度もビルドを実行し、システム全体の状態を把握した上で、問題点をすぐに検出できる仕組みを作ることを、継続的インテグレーションと言います。Jenkinsのようにこのような仕組みを導入できるツールと組み合わせ、テストコードの効果をより高めることができます。


