2012/07/27
JUnit3 で Parameterized test case (1)
しかし、JUnit3 にはそのような機能がないため、本来はパラメータ毎にテストメソッドを記述しなければなりません。
なんてイマイチな仕様なんだ…
しかし、よく考えてみると、
TestSuite
を利用すれば、JUnit4 と同じように Parameterized test が出来ることに気づきました。以下、やってみた結果です。
今回、作成したプロジェクトは以下においてあります。
ご自由にお使いください。
JUnit3Experiment_01.zip
2012/7/28 追記
テスト対象を準備
まずは、テスト対象のプログラムを作成します。今回は、入力値の2倍を返すメソッド、入力値の自乗を返すメソッドの2つを用意してみました。 あえて、バグを仕込んであります。
MyUtils.java
public class MyUtils { public static int calcTwice(int a) { if (a < 100) { return a * 2; } else { // 100 以上の場合は間違える Bug return a; } } public static int calcSquare(int a) { if (a < 100) { return a * a; } else { // 100 以上の場合は間違える Bug return a; } } }
TestCase を作成
テストを書きます。calcTwice(int)
の TestCase は以下です。CalcTwiceTest.java
public class CalcTwiceTest extends TestCase { private final int mExpected; private final int mInput; CalcTwiceTest(int number, int expected, int input) { // テスト名がユニークになるようにする super("TwiceTest " + number); mExpected = expected; mInput = input; } @Override protected void runTest() throws Throwable { int result = MyUtils.calcTwice(mInput); assertEquals("input " + mInput, mExpected, result); } }
このとき、コンストラクタにパラメータを取るようにします。
後ほど説明しますが、パラメータの数だけ TestCase インスタンスが作成されることになります。
そのため、親コンストラクタに名前を明示的に指定して、重複しないようにしなければなりません。
「クラス名+[数字or特徴的なパラメータ]」にするのが良いでしょう。
また、
runTest()
をオーバーライドして、テストを記述します。JUnit に慣れている方は、「おや?」と思ったかもしれません。
普通、JUnit では、
testXXX()
がテストメソッドとして自動的に使用されますので、runTest()
を明示的にオーバーライドすることはありません。しかし、今回のようにコンストラクタを独自形式にした場合、この機能が働きませんので、このような形式にする必要があるのです。
同様に、
calcSquare(int)
の TestCase
は以下のようになります。CalcSquareTest.java
public class CalcSquareTest extends TestCase { private final int mExpected; private final int mInput; CalcSquareTest(int number, int expected, int input) { // テスト名がユニークになるようにする super("SquareTest " + number); mExpected = expected; mInput = input; } @Override protected void runTest() throws Throwable { int result = MyUtils.calcSquare(mInput); assertEquals("input " + mInput, mExpected, result); } }
TestSuite の作成
TestSuite
とは、複数の TestCase
をまとめたものです。今回は、各パラメータ毎に
TestCase
のインスタンスを作成し、それらをまとめて TestSuite
とします。AllTests.java
public class AllTests { // Test Data // 本当はFile等から取り込む private static int[][] sTwiceTestData = { {5, 10}, {8, 16}, {20, 40}, {21, 42}, {103, 206} }; // Test Data // 本当はFile等から取り込む private static int[][] sSquareTestData = { {5, 25}, {8, 64}, {20, 400}, {21, 441}, {103, 10609} }; public static Test suite() { TestSuite suite = new TestSuite(AllTests.class.getName()); //$JUnit-BEGIN$ for (int i = 0; i < sTwiceTestData.length; i++) { suite.addTest(new CalcTwiceTest(i, sTwiceTestData[i][1], sTwiceTestData[i][0])); } for (int i = 0; i < sSquareTestData.length; i++) { suite.addTest(new CalcSquareTest(i, sSquareTestData[i][1], sSquareTestData[i][0])); } //$JUnit-END$ return suite; } }
Test の実行
Eclipse の場合、以下のようにTestSuite
を実行します。AllTests.java を選択
Run As → JUnit Test
Eclipse JUnit Launcher を選択。
以下のような結果になりました。
ちゃんと、パラメータ毎に動作しています。バグもバッチリひろっていますね。
この方法、JUnit3 の思想的にどうなのか微妙なところですが、形式的にはJUnit4に近いですし、TestCase クラスの JavaDoc には、
と書いてるので、上記のようなテストケースを作成するのは想定内のように思います。Override to run the test and assert its state.
0 件のコメント:
コメントを投稿