1. 概要

この記事では、JUnitParamsライブラリとその使用法について説明します。 簡単に言えば、このライブラリは、JUnitテストのテストメソッドの簡単なパラメーター化を提供します。

複数のテスト間で変更されるのはパラメーターだけである場合があります。 JUnit 自体はパラメーター化をサポートしており、JUnitParamsはその機能を大幅に改善しています。

2. Mavenの依存関係

プロジェクトでJUnitParamsを使用するには、それをpom.xmlに追加する必要があります。

<dependency>
    <groupId>pl.pragmatists</groupId>
    <artifactId>JUnitParams</artifactId>
    <version>1.1.0</version>
</dependency>

ライブラリの最新バージョンはここにあります。

3. テストシナリオ

2つの整数を安全に加算するクラスを作成しましょう。 これにより、オーバーフローした場合は Integer.MAX_VALUE が返され、アンダーフローした場合はInteger.MIN_VALUEが返されます。

public class SafeAdditionUtil {

    public int safeAdd(int a, int b) {
        long result = ((long) a) + b;
        if (result > Integer.MAX_VALUE) {
            return Integer.MAX_VALUE;
        } else if (result < Integer.MIN_VALUE) {
            return Integer.MIN_VALUE;
        }
        return (int) result;
    }
}

4. 簡単なテストメソッドの構築

入力値のさまざまな組み合わせについてメソッドの実装をテストし、考えられるすべてのシナリオで実装が当てはまることを確認する必要があります。 JUnitParams は、パラメーター化されたテストの作成を実現するための複数の方法を提供します。

最小限のコーディングで基本的なアプローチを取り、それがどのように行われるかを見てみましょう。 その後、JUnitParamsを使用してテストシナリオを実装する他の可能な方法が何であるかを確認できます

@RunWith(JUnitParamsRunner.class)
public class SafeAdditionUtilTest {

    private SafeAdditionUtil serviceUnderTest
      = new SafeAdditionUtil();

    @Test
    @Parameters({ 
      "1, 2, 3", 
      "-10, 30, 20", 
      "15, -5, 10", 
      "-5, -10, -15" })
    public void whenWithAnnotationProvidedParams_thenSafeAdd(
      int a, int b, int expectedValue) {
 
        assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
    }

}

次に、このテストクラスが通常のJUnitテストクラスとどのように異なるかを見てみましょう。

最初に気付くのは、クラスアノテーションに異なるテストランナーがあることです– JUnitParamsRunner

テストメソッドに移ると、テストメソッドに入力パラメーターの配列を含む@Parametersアノテーションが付けられていることがわかります。 これは、サービス方法のテストに使用されるさまざまなテストシナリオを示しています。

Mavenを使用してテストを実行すると、1つのテストケースではなく4つのテストケースを実行していることがわかります。 出力は次のようになります。

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.baeldung.junitparams.SafeAdditionUtilTest
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.068 sec 
  - in com.baeldung.junitparams.SafeAdditionUtilTest

Results :

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0

5. テストメソッドのさまざまなタイプのパラメータ化

テストする必要のあるシナリオがたくさんある場合、アノテーションに直接テストパラメータを提供することは確かに最も読みやすい方法ではありません。 JUnitParams は、パラメーター化されたテストを作成するために利用できる一連のさまざまなアプローチを提供します。

  • @Parameters アノテーションに直接(上記の例で使用)
  • アノテーション内で定義された名前付きテストメソッドを使用する
  • テストメソッド名でマップされたメソッドを使用する
  • アノテーション内で定義された名前付きテストクラス
  • CSVファイルを使用する

アプローチを1つずつ見ていきましょう。

5.1. @Parametersアノテーションで直接

試した例では、すでにこのアプローチを使用しています。 覚えておく必要があるのは、パラメータ文字列の配列を提供する必要があるということです。 パラメータ文字列内では、各パラメータはコンマで区切られます。

たとえば、配列は {“ 1、2、3”、“ -10、30、20”} の形式になり、パラメータの1つのセットは“ 1、2として表されます。 、3インチ

このアプローチの制限は、テストパラメータとしてプリミティブとStringのみを提供できることです。 テストメソッドパラメータとしてオブジェクトを送信することもできません。

5.2. パラメータメソッド

クラス内の別のメソッドを使用して、テストメソッドパラメーターを提供できます。 最初に例を見てみましょう。

@Test
@Parameters(method = "parametersToTestAdd")
public void whenWithNamedMethod_thenSafeAdd(
  int a, int b, int expectedValue) {
 
    assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
}

private Object[] parametersToTestAdd() {
    return new Object[] { 
        new Object[] { 1, 2, 3 }, 
        new Object[] { -10, 30, 20 }, 
        new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, 
        new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } 
    };
}

テストメソッドは、メソッド parametersToAdd()、に関して注釈が付けられ、参照されたメソッドを実行することによってパラメーターをフェッチします。

プロバイダーメソッドを指定すると、結果としてObjectの配列が返されます。 指定された名前のメソッドが使用できない場合、テストケースは次のエラーで失敗します。

java.lang.RuntimeException: Could not find method: bogusMethodName so no params were used.

5.3. テストメソッド名によってマップされたメソッド

@Parameters アノテーションに何も指定しない場合、 JUnitParams は、テストメソッド名に基づいてテストデータプロバイダーメソッドをロードしようとします。 メソッド名は次のように構成されます 「parametersFor」+

@Test
@Parameters
public void whenWithnoParam_thenLoadByNameSafeAdd(
  int a, int b, int expectedValue) {
 
    assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
}

private Object[] parametersForWhenWithnoParam_thenLoadByNameSafe() {
    return new Object[] { 
        new Object[] { 1, 2, 3 }, 
        new Object[] { -10, 30, 20 }, 
        new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, 
        new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } 
    };
}

上記の例では、テストメソッドの名前は whenWithnoParam_shouldLoadByNameAbdSafeAdd()です。

したがって、テストメソッドが実行されているときは、 parametersForWhenWithnoParam_shouldLoadByNameAbdSafeAdd()という名前のデータプロバイダーメソッドが検索されます。

そのメソッドが存在するため、そこからデータをロードしてテストを実行します。 必要な名前に一致するそのようなメソッドがない場合、上記の例のようにテストは失敗します

5.4. アノテーション内で定義された名前付きテストクラス

前の例でデータプロバイダーメソッドを参照した方法と同様に、別のクラスを参照して、テスト用のデータを提供できます。

@Test
@Parameters(source = TestDataProvider.class)
public void whenWithNamedClass_thenSafeAdd(
  int a, int b, int expectedValue) {
 
    assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
}
public class TestDataProvider {

    public static Object[] provideBasicData() {
        return new Object[] { 
            new Object[] { 1, 2, 3 }, 
            new Object[] { -10, 30, 20 }, 
            new Object[] { 15, -5, 10 }, 
            new Object[] { -5, -10, -15 } 
        };
    }

    public static Object[] provideEdgeCaseData() {
        return new Object[] { 
            new Object[] { 
              Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, 
            new Object[] { 
              Integer.MIN_VALUE, -2, Integer.MIN_VALUE }, 
        };
    }
}

メソッド名が「provide」で始まる場合、クラスには任意の数のテストデータプロバイダーを含めることができます。 その場合、エグゼキュータはそれらのメソッドを選択し、データを返します。

その要件を満たすクラスメソッドがない場合、それらのメソッドが Object の配列を返しても、それらのメソッドは無視されます。

5.5. CSVファイルの使用

外部CSVファイルを使用してテストデータをロードできます。 これは、可能なテストケースの数が非常に多い場合、またはテストケースが頻繁に変更される場合に役立ちます。 変更は、テストコードに影響を与えることなく実行できます。

テストパラメータがJunitParamsTestParameters.csvのCSVファイルがあるとします。

1,2,3
-10, 30, 20
15, -5, 10
-5, -10, -15

次に、このファイルを使用してテストメソッドのテストパラメータをロードする方法を見てみましょう。

@Test
@FileParameters("src/test/resources/JunitParamsTestParameters.csv")
public void whenWithCsvFile_thenSafeAdd(
  int a, int b, int expectedValue) {
 
    assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
}

このアプローチの1つの制限は、複雑なオブジェクトを渡すことができないことです。 プリミティブとStringのみが有効です。

6. 結論

このチュートリアルでは、JUnitParamsの機能を簡単に活用する方法を説明しました。

また、ライブラリがテストメソッドにテストパラメータを提供するために提供するさまざまなアプローチについても説明しました。これは、JUnit自体が実行できる範囲をはるかに超えています。

いつものように、ソースコードはGitHubにあります。