TDD(テスト駆動開発)という開発方法が浸透してきています。プログラミングを始めるにあたり、事前に単体テストを行うためのコードを書くことを、ごく当たり前のように思っているプログラマーも増えてきました。TDDではさまざまなツールを使用することが必要不可欠ですが、「ツールを使うことイコールTDD」ではありません。ここではTDDとテストツールの関連性について整理していきましょう。
TDDの進め方については、下記のコラムを参照してください。
1.TDDの基本ツール「xUnit」
プログラミング言語にはさまざまな種類が存在します。その多くの言語には単体テストや結合テストを行うためのツールであるテスティングフレームワークが用意されています。
その多くが「○○Unit」という名前であるため、総称として「xUnit(エックスユニット)」と呼ばれています。
例えば、JavaにはJUnit、PHPにはPHPUnit、C#やVB.NETといった.NET系の言語であれば、NUnitといったツールがあり、これを用いて単体テストを行えるようになっています。xUnitという名前ではありませんが、他にもJava用のTestNGや、Python用のunittest、Ruby用のTest::Unitなどが有名です。
厳密に言えば、テスティングフレームワークを使用しなくともTDDは実施できます。
しかしその場合、本コードの間にデバッグ用のコードを書く必要があります。そのようにひとつのファイルの中に本コードとテストコードが混在すると、そのソースコード上で何をやろうとしているのかが分かりづらくなります。
さらに、本番リリース時にテストコードを削除しようとすると、その時にミスが生じ、バグが混入してしまう可能性が出てしまいます。それでは本末転倒です。プログラムの世界において、バグを混入させないコツは「プログラムを書かないこと」なのです。
これらのテスティングフレームワークを使用することで、テスト対象のソースコード(プロダクトコードや本コードと言ったりします)の内部にテスト用のコードを追加することなく、別のファイルとしてテストコードを作成することができます。
また、実行したテストのうち、何件テストをパス(合格)し、何件が不合格だったのかが分かりやすく表示されるとともに、どのテストがどのような理由で不合格となったかも明確になります。
TDDで開発を進める上では、xUnit系のテストツールを使用することは必要不可欠です。また、TDDでなくても、テストコードを書いて単体テストを実施するのであれば、こうしたテスティングフレームワークを使用することは必須といっていいでしょう。
2.チームでのTDDを促進するツール
TDDを実施するうえで、他にも使用した方がよいツールがあります。
特に一人で開発を進めるのではなく、複数人での開発を行う場合であれば、ここから紹介するビルドツール、バージョン管理ツール、CIツール、モックオブジェクトライブラリを使用することで格段にTDDがやりやすくなるでしょう。
また、ひとつのソースコードが対象の単体テストではなく、いくつかのソースコードやライブラリを組み合わせて実施する結合テストまでスコープに入れる場合にも役に立ちます。
2-1 ビルドツール
ビルドツールとは作成したプログラムを実行可能な状態にするために必要な作業を行うツールです。
この作業をビルド作業といい、複数のソースコードをまとめてコンパイルしたり、使用するライブラリへのパスを通したり、テストコードを実行したり、ファイルをクリーンアップしたりと、状況に応じてさまざまな作業が必要になります。
手動でこれらの作業を毎回行うのは、一回一回は大したことはありませんが、TDDでは何度も実行と修正を繰り返すため、総合すると大変な労力です。これらのツールを使用して可能な限り自動化を進めておく必要があります。
有名なものにはMavenやGradle、antなどがあります。
2-2 バージョン管理ツール
バージョン管理ツールは、ソースコードの作成や修正を行った際に、その履歴を管理します。そして、問題のある変更があった場合にはそれを通知し、場合によっては前のバージョンへ差し戻すことができるツールです。
このツールが威力を発揮するのは、複数人で同時に開発を進める場合です。同じファイルを同時に更新した場合、バージョン管理ツールを導入していれば、同じ箇所の変更があればそれを教えてくれます。問題を解消して更新することで、ファイルの先祖返りやデグレードを最小限にすることができます。
TDDではソースコードの修正やリファクタリングを前提としているため、バージョン管理ツールも欠かせないものといえるでしょう。
バージョン管理ツールには、SubversionやGitなどが主に使われています。
2-3 CIツール
継続的インテグレーション(CI)ツールは、その名の通り定期的、継続的にソースコードの統合(インテグレーション)を実行するツールです。
具体的には、ビルドツールと連携して1時間おきにソースコード全体をコンパイル、結合し、実行可能な状態にビルドしたり、先ほど紹介したバージョン管理ツールと連携して、ソースコードの更新があるたびにビルドや、TDDで作成したテストコードの実行を行ったりします。
CIツールの導入により、ソースコードの更新で問題がある箇所が発生した場合のフィードバックのタイムラグが短くなります。ソースコードを修正した際に、自分の担当している部分では問題がなくても、他の人の書いた部分に対して問題が発生することもあります。そのときにCIツールを導入し、定期的に、あるいは変更をトリガーとしてテストコードを実行していれば、テストコードで不合格となったときにその内容を通知してくれます。TDDで開発を実行している場合は、CIによるビルド時にそのテストコードを流用でき、効率的に複数人での開発を行うことができます。
有名なCIツールには、Jenkinsがあります。また最近ではクラウドサービスのTravisCIやCircleCIもよく使われています。
2-4 モックオブジェクトライブラリ
モックオブジェクトライブラリは、実装されていない機能を疑似的に呼び出すために使用する機能です。
たとえばDBのデータを取得して、値を計算するような処理の場合、本来はDB側の処理が実装されていないとテストすることができません。そこで、モックオブジェクトを使用すれば、あたかもDBからデータを取得してきたかのように、値を取得することができます。
モックとはモックアップの略称で、もともとの意味は原寸大の模型のことです。モックオブジェクトライブラリを使用することで、連携する機能に未完成の部分があったとしても、単体での開発を進めることができます。
代表的なモックオブジェクトライブラリは、JavaのMockito(モヒート)などがあげられます。PythonやPHPなど他の言語ではxUnit系のツールに盛り込まれていることが多いです。
モックオブジェクトライブラリは非常に便利なツールではありますが、多用しすぎるとメンテナンス性が低下するため、必要最低限の使用に留めることが大切です。あまりにもモックオブジェクトに依存しすぎるようであれば、システムアーキテクチャを見直した方がいい場合もあります。
まとめ
プログラマーがテストを行うためのツールはこの他にも多数存在します。
Javaで静的解析を行ってくれるspotbugs(以前はfindbugsという名前のツールでしたが、メンテナンスが停止したため、新しく引き継がれたツールです)や、WebアプリのUIのテストを自動化できるSeleniumやcapybaraなどのようなツールが存在します。
このほかにも言語や環境に応じたさまざまなテストツールが存在し、プログラマーの作業を助けてくれます。ただ、TDDを実施するうえで必須、というわけではありません。プロジェクトやソフトウェアの特性に応じて取捨選択していくといいでしょう。