JUnitParamsの概要
1. 概要
この記事では、JUnitParamsライブラリとその使用法について説明します。 簡単に言えば、このライブラリは、JUnitテストのテストメソッドの簡単なパラメータ化を提供します。
複数のテスト間で変更されるのはパラメーターのみである場合があります。 JUnit自体にパラメーター化のサポートがあり、JUnitParamsはその機能を大幅に改善します。
2. メーベン依存
プロジェクトでJUnitParamsを使用するには、pom.xmlに追加する必要があります。
pl.pragmatists
JUnitParams
1.1.0
ライブラリの最新バージョンはhereにあります。
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テストクラスとどのように異なるかを見てみましょう。
最初に気付くのは、クラスアノテーションのthere is adifferent test runner –JUnitParamsRunnerです。
テストメソッドに移ると、テストメソッドに入力パラメーターの配列を含む@Parametersアノテーションが付けられていることがわかります。 サービスメソッドのテストに使用されるさまざまなテストシナリオを示しています。
Mavenを使用してテストを実行すると、we are running four test cases and not a single oneが表示されます。 出力は次のようになります。
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.example.junitparams.SafeAdditionUtilTest
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.068 sec
- in com.example.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”として表されます。
このアプローチの制限は、テストパラメーターとしてプリミティブとStringsしか提供できないことです。 オブジェクトをテストメソッドパラメータとして送信することもできません。
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(),に関する注釈が付けられ、参照されたメソッドを実行してパラメーターをフェッチします。
プロバイダーメソッドを指定すると、結果としてObjectsの配列が返されます。 指定された名前のメソッドが利用できない場合、テストケースはエラーで失敗します。
java.lang.RuntimeException: Could not find method: bogusMethodName so no params were used.
5.3. テストメソッド名によってマップされたメソッド
@Parametersアノテーションに何も指定しない場合、JUnitParamsはテストメソッド名に基づいてテストデータプロバイダーメソッドをロードしようとします。 メソッド名は“parametersFor”+ <test method name>:として構成されます
@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()という名前のデータプロバイダーメソッドが検索されます。
このメソッドは存在するため、そこからデータをロードしてテストを実行します。 上記の例のようにIf there is no such method matching the required name, the test fails。
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」で始まる場合、クラスにテストデータプロバイダーをいくつでも含めることができます。 その場合、エグゼキュータはそれらのメソッドを選択してデータを返します。
その要件を満たすクラスメソッドがない場合、それらのメソッドがObjectsの配列を返しても、それらのメソッドは無視されます。
5.5. CSVファイルの使用
外部CSVファイルを使用して、テストデータを読み込むことができます。 これは、可能なテストケースの数が非常に多い場合、またはテストケースが頻繁に変更される場合に役立ちます。 テストコードに影響を与えずに変更を行うことができます。
テストパラメータがJunitParamsTestParameters.csvのCSVファイルがあるとします。
1,2,3
-10, 30, 20
15, -5, 10
-5, -10, -15
次に、テストメソッドのthis file can be used to load test parametersがどのようになっているのかを見てみましょう。
@Test
@FileParameters("src/test/resources/JunitParamsTestParameters.csv")
public void whenWithCsvFile_thenSafeAdd(
int a, int b, int expectedValue) {
assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
}
このアプローチの1つの制限は、複雑なオブジェクトを渡すことができないことです。 プリミティブとStringsのみが有効です。
6. 結論
このチュートリアルでは、JUnitParamsの機能を簡単に利用する方法を説明しました。
また、ライブラリがテストメソッドにテストパラメータを提供するために提供するさまざまなアプローチについても説明しました。これは、JUnit自体ができることをはるかに超えています。
いつものように、ソースコードはover on GitHubで見つけることができます。