テスト駆動開発(Test-Driven Development、略称TDD)とは、まずテストコードを書いた後にそのテストをパスするようにプロダクト本体を実装する開発手法です。
テスト駆動開発の実施手順やメリット、デメリットなどについてご紹介します。
テスト駆動開発とは?
テスト駆動開発は先に書いたテストが成功するような最低限の実装を心がけることで、要件を満たしながらシンプルで美しいコードにするための手法です。プロダクトの品質が高くなる、追加開発の際のストレスが減るといった効果があります。
テスト駆動開発自体は 1980年代から提唱されていましたが、大きく普及するきっかけとなったのは2002年にKent Beck氏が執筆した書籍「Test Driven Development By Example」です。この本にはテスト駆動開発の基本理念や後に解説するテスト駆動開発の基本サイクル、テストのデザインパターン等が体系的にまとめられています。
2000年代以降注目されるようになったアジャイルの手法の多くでもテスト駆動開発が推奨されており、エクストリームプログラミング(XP)のベストプラクティスの中にも含まれています。
テスト駆動開発の基本サイクル
テスト駆動開発は「Red 」「Green」「Refactor」という3つのステップから成るサイクルで進めます。Red、Greenはテストツールによるテストが失敗すると赤色、成功すると緑色の表示となることからこう呼ばれています。
Red
まずはテストコードを書きます。この時点では実装を行っていないため、テストは必ず失敗します。
Green
続いて先に書いたテストが成功するように機能を実装します。このステップではテストが成功する(要件を満たす)最低限のコードを書きます。
Refactor
テストがすべて成功となった後に、プログラムを修正して可読性・拡張性・保守性を高めます。このステップはテストが成功した後出来るだけ早く行うことが重要です。
テスト駆動開発のメリット
テスト駆動開発のメリットをさらに詳しくご紹介します。特に頻繁にコードに手を入れるプロダクトや開発手法ではメリットが大きいです。
実装がシンプルになる
テストが成功する(要件を満たせる)最低限のコードを書いていくので、実装をシンプルにすることが出来ます。シンプルな実装にすることで見通しが良くなり、バグも混入しにくくなります。
また、最初に実装した開発者とは別の人が修正を加える場合にも少ない時間で理解が可能となり、工数の削減が期待できます。
早い段階でバグを検知できる
先にテストを書くことで実装が完了した後すぐにテストすることができます。そのためまだ実装した記憶が新しい段階で多くのバグを除去することができます。
仕様への理解が深まる
全パターンを網羅するような(テストコード実行時にソースコードのカバレッジが100%になるような)テストを作成することで、仕様の理解が深まります。また、仕様と実装との間に齟齬が発生した場合にもすぐに検知することができます。
追加開発の際にプログラムを壊すことを防ぐことができる
追加開発・リファクタリングの際に既存のテストが成功するかどうかで、プログラムを壊していないか確認することができます。
万が一デグレードを起こしてしまった場合にもすぐ検知し修正することができるので、追加開発が多いプログラムや、何度も開発のサイクルを繰り返すアジャイルの手法では特に有効です。
テスト駆動開発のデメリット
一方テスト駆動開発にはデメリットもあります。以下では主なデメリットについて解説いたします。
テストのメンテナンスに工数がかかる
一度書いたテストは、プログラムとともに保守し続ける必要があります。導入する際にはその負担をチームに理解してもらう必要があります。
メンテナンス不良のテストによるバグ混入のリスクがある
追加開発の際に既存のテストケースの修正が必要であるにも関わらずそれを見逃した場合、「テストを成功させる実装」が間違いであったということが起こりえます。
またテストコードの修正が不十分なために一部失敗することが常態化した場合、テストが「オオカミ少年」となってバグが原因で失敗しているケースを見逃すおそれがあります。
GUI等のテストには向かない
画面表示に関わるものなど、テストコードが書きにくい、あるいは書くためにかかる工数が保証できる品質に見合わないプログラムもあります。
その個所については最初にテストコードを書かずその後の結合テストフェーズで網羅的なテストを行う等、工夫が必要です。
定着するまでは開発者のストレスになり得る
特に慣れるまでは、要件を全網羅するテストを書くには工数がかかります。今までテストを書く文化がなかったチームの場合、そのために工数を割くことを理解してもらう必要があります。また、新しい文化が定着するまでには開発者のストレスも大きくなるかもしれません。
テスト駆動開発でよく用いられるツール
テスティングフレームワーク
テスティングフレームワークは実際に単体テストを行うためのツールです。
テストコードを実行することでテスト対象のプログラムを呼び出し、ケースをもとに検証を行なって結果を判定、集計する機能を提供します。
テスティングフレームワークを使用することで、テスト対象のプログラムとテスト用コードを分離することができます。
さらにテスト実行時にソースコードの何%を網羅したか(カバレッジ)も測定してくれます。これはどれだけ網羅的なテストケースを作成できているかの指標になります。
加えてテストのテンプレートやライブラリなどテストコードがより簡単に書けるようなツールも備えています。
代表的なテスティングフレームワークにxUnitがあります。これは〇〇Unitという名称のフレームワークの総称で、具体的にはJavaのプログラムのテストのためのフレークワークであるJunit、PHP用のPHPUnit、Python用のPyUnit等を指します。
ビルドツール
ビルドツールはプログラムのコンパイル、ライブラリの依存関係の解消等を行い、プログラムを実行可能な状態にする「ビルド」のタスクを登録し、実行するためのツールです。プログラムファイルに変更があった場合に自動的にビルドを行うことも可能です。
ビルドツールを使って自動化することで、プログラムの変更とテスト実行を短いサイクルで繰り返すテスト駆動開発におけるビルドの手間を減らすことができます。
代表的なビルドツールにはAnt、Mavenがあります。
継続的インテグレーションツール
継続的インテグレーションは、開発者がコードをメインリポジトリにコミットするたびに自動化されたビルドとテストを実行する開発手法です。
継続的インテグレーションツールを用いて、コードをコミット後にサーバー上でビルド→テスト実行→テスト環境にデプロイというサイクルを自動化することができます。
複数人での開発において継続的インテグレーションツールを導入することで、頻繁に発生するコードの修正後のテスト実行・デプロイを効率化することができます。
最もよく知られている継続的インテグレーションツールはJenkinsです。
4.まとめ
テスト駆動開発は1から始める際にはパワーが必要ですが、うまく軌道に乗せることができれば品質の向上が期待できます。特に頻繁に追加開発があるプロダクトではメリットが大きくなります。各種ツールを最大限活用しながら、導入を検討してみてください。
- カテゴリ:
- キーワード: