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 件のコメント:
コメントを投稿