2012/07/27
JUnit3 で Parameterized test case (1)
しかし、JUnit3 にはそのような機能がないため、本来はパラメータ毎にテストメソッドを記述しなければなりません。
なんてイマイチな仕様なんだ…
しかし、よく考えてみると、
TestSuite
を利用すれば、JUnit4 と同じように Parameterized test が出来ることに気づきました。以下、やってみた結果です。
今回、作成したプロジェクトは以下においてあります。
ご自由にお使いください。
JUnit3Experiment_01.zip
2012/7/28 追記
テスト対象を準備
まずは、テスト対象のプログラムを作成します。今回は、入力値の2倍を返すメソッド、入力値の自乗を返すメソッドの2つを用意してみました。 あえて、バグを仕込んであります。
MyUtils.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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 件のコメント:
コメントを投稿