web-dev-qa-db-ja.com

Javaデータプロバイダーを使用したテストの記述

現在、最初のJavaプロジェクトをやっており、TDDを完全にやりたい。テストの作成にJUnitを使用している。明らかにJUnitは data provider のサポートを提供していない=、20の異なるバージョンの引数で同じメソッドをテストするのはかなり面倒です。Javaデータプロバイダーをサポートする最も一般的/標準のテストツールは何ですか? TestNG 、しかし、それがどれほど人気が​​あるか、または他の選択肢と比較する方法がわかりません。

この動作を取得する方法がJUnitを使用してすてきな方法である場合、それも機能する可能性があります。

30
Jeroen De Dauw

JUnit 4には、PHPデータプロバイダーと同じことを行うパラメーター化されたテストがあります

@RunWith(Parameterized.class)
public class MyTest{ 
     @Parameters
    public static Collection<Object[]> data() {
           /*create and return a Collection
             of Objects arrays here. 
             Each element in each array is 
             a parameter to your constructor.
            */

    }

    private int a,b,c;


    public MyTest(int a, int b, int c) {
            this.a= a;
            this.b = b;
            this.c = c;
    }

    @Test
    public void test() {
          //do your test with a,b
    }

    @Test
    public void testC(){
        //you can have multiple tests 
        //which all will run

        //...test c
    }
}
29
dkatzel

私たちの会社の同僚は、JUnit用のTestNGスタイルで自由に利用可能なDataProviderを作成しました。これは on github(https://github.com/TNG/junit-dataprovider) にあります。

私たちは非常に大規模なプロジェクトでそれを使用し、私たちにとってはうまく機能します。 JUnitのParameterizedに比べていくつかの利点があり、個別のクラスのオーバーヘッドを削減し、単一のテストも実行できます。

例は次のようになります

@DataProvider
public static Object[][] provideStringAndExpectedLength() {
    return new Object[][] {
        { "Hello World", 11 },
        { "Foo", 3 }
    };
}

@Test
@UseDataProvider( "provideStringAndExpectedLength" )
public void testCalculateLength( String input, int expectedLength ) {
    assertThat( calculateLength( input ) ).isEqualTo( expectedLength );
}

Edit:v1.7以降、データ(文字列、リスト)を提供する他の方法もサポートし、別のメソッドが必然的に。

完全で実用的な例は、githubのマニュアルページにあります。また、ユーティリティクラスでプロバイダーを収集したり、他のクラスからアクセスしたりするなど、いくつかの機能が追加されています。

41
Ingo Bürk

柔軟性と読みやすさのニーズに応じて、Parameterized-dkatzelで説明されているjunitの組み込みオプションを選択できます。他のオプションは zohhak のような外部ライブラリによって提供される外部junitランナーです。

 @TestWith({
        "clerk,      45'000 USD, GOLD",
        "supervisor, 60'000 GBP, PLATINUM"
    })
    public void canAcceptDebit(Employee employee, Money money, ClientType clientType) {
        assertTrue(   employee.canAcceptDebit(money, clientType)   );
    }

または junitParams 少し機能が異なります。あなたに最も合ったものを選んでください

7
piotrek

別のオプションがあります。 Google Guavaを使用する必要はありません。これは単なる実装です。

これは@dkatzelの答えと同じ@Parametersを使用しますが、引数を取るクラスの代わりに@Parametersアノテーションは特定のテストメソッドに適用されるため、その引数セットを使用するメソッドを選択できます。

import Java.util.Collection;

import com.google.common.collect.ImmutableList;

import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JUnitParamsRunner.class)
public class FrobTester {
    @SuppressWarnings("unused")
    private Collection validfrobAndGorpValues() {
        return ImmutableList.of(
            new Object[] {"frob28953", 28953},
            new Object[] {"oldfrob-189-255", 1890255}
        );
    }

    @Test
    @Parameters(method = "validfrobAndGorpValues")
    public void whenGivenFrobString_thenGorpIsCorrect(
        String frobString,
        int expectedGorpValue
    ) {
        Frob frob = new Frob(frobString);
        Assert.assertEquals(expectedGorpValue, frob.getGorpValue());
    }
}
1
ErikE