Technology & Programming Article
一段上を行くテスティング・テクニック20選
JUnitスーパーTips
第1回 基礎編
ユニット・テスト(単体テスト)用フレームワークのデファクト・スタンダードとも言われるJUnitだが、実際には、これをそのまま使うだけでは、実現できないテストも多い。他の優れたフレームワークと同様に、JUnitも、利用者の目的に合わせた拡張やカスタマイズが必要なのだ。本連載では5回にわたって、このJUnitをテスト・ツールとしてより効果的に使う、あるいはテストや設計を改善するためのツールとしても活用するという観点から、20個のTipsをお届けする。第1回となる今回は、多くのテストに共通して適用可能な基本的なTipsを紹介する。
2006年3月6日更新
テストの前処理を1回だけにする──テストの高速化──
解決すべき問題
JUnitでは、テスト・ケースのスーパークラスとなるクラスjunit.framework.TestCaseに、テストの前処理/後処理を行うためのメソッドsetUp/tearDownが用意されている。これらは、各テスト・メソッド(テスト・ケースに書かれたテスト用のメソッド)が呼び出される度に実行される。
テストの前処理が時間のかかるものである場合、テスト・ケースの数が増えると、テスト全体を実行するのに多大な時間を費やすことになる。つまり、ちょっとした変更に対する安全性の確認のために、長い時間をかけてテストを実行しなければならず、開発の効率が悪くなってしまうのだ。なかには、それが原因でテストを行わなくなる人が出てくる。
解法と効果
この問題に対する1つの解は、「前処理を1回だけ実行するようにする」というものになる。各テストによって副作用が発生することがない(テストの実行によって、何らかの状態の変更が生じることがない)、あるいは副作用が発生したとしても、それを初期化できるという前提条件を満たす場合に、前処理を1回だけで済ませるかたちでテストを行うことができる。これにより、GUIも含めてテストしているようなケースなどでは、実行時間が大幅に短縮されるだろう。
以下、具体的な解決法を2つ紹介する。
1つのテスト・ケースに対する解法
まず、1つのテスト・ケースにおいて、テスト・メソッドがいくつあるかにかかわらず、1回だけ前処理が行われるようにする方法をご覧いただこう。
リスト1に示したテスト・ケースでは、メソッドsuiteで、通常のjunit.framework.TestSuiteオブジェクト(テスト・スイート)を返すのではなく、TestSuiteオブジェクトを保持するjunit.extensions.TestSetupオブジェクトを返すようにしている。これにより、オーバーライドしたメソッドTestSetup.setUp(ならびに、メソッドTestSetup.tearDown)が、メソッドTestSuite.runが呼び出される前後で実行される仕組みとなっている。
| リスト1:1つのテスト・ケースの実行時に1回だけ前処理を行う例 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
この方法の場合、通常のJUnitのテストと同様に実行できる。
複数のテスト・ケースに対する解法
続いて、複数のテスト・ケースをまとめて一度に実行する際、1つ目のテスト・ケースの実行前に、1回だけ前処理を行う方法を見ていただこう。
リスト2に示したのが、その実装例である。この方法では、JUnit自体に変更を加えることなく動作を拡張していることになり、TestSuiteオブジェクトを実行する前後で、好きなように前処理と後処理を記述できる。
| リスト2:複数のテスト・ケースの実行時に、1回だけ前処理を行う例(その1) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
ただし、この方法の場合、複数のテスト・ケースを通常のJavaアプリケーションとして実行することになる。
さらなる応用例
上記のどちらの方法においても、各テストに副作用がない場合、クラスTestCaseのメソッドsetUpをオーバーライドする必要はない。一方、副作用がある場合には、クラスTestCaseのメソッドsetUpで副作用を初期化する処理を行う。
ここでは、一般的に紹介されている2つの方法を取り上げたが※1、後者の方法の場合、メソッドmainから実行することになるため、統合開発環境(IDE)として「Eclipse」を用いている場合、通常のJUnitの利用法とは異なることになり、多少使い勝手が悪い。このことが問題になるなら、前者の方法を併用し、リスト3のようにして複数のテスト・ケースを実行するとよいだろう。クラスTestCaseを拡張したクラスにテスト・メソッドが1つも記述されていないというのは多少気持ち悪いが、これであれば、通常のJUnitのテストと同様に実行できる。
※1 ここで示した方法は、『JUnit Recipes: Practical Methods for Programmer Testing』(著者:J.B.レインズバーガー、スコット・スターリング/発行:Manning Publications/発行年:2004年)を参考にしたものである。
| リスト3:複数のテスト・ケースの実行時に、1回だけ前処理を行う例(その2) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|









