社の読書会で「単体テストの考え方/使い方」を読んでます。
本書の中でパラメタライズドテスト(パラメータ化テスト)について紹介されており、JUnitでどのように書くのか調べました。
いくつかパターンがあったのでそれぞれ紹介します。
※JUnitでのパラメタライズドテストを紹介しているだけで、パラメタライズドテストを強く推奨している意図はありません。
JUnit4のParameterized
JUnit4にParameterizedクラスがありそれを使う方法
@RunWith(Parameterized::class) class SquaredTestJUnit4ParameterizeTest { companion object { @Parameters @JvmStatic fun getData() = arrayOf<Squared>( Squared(1, 1), Squared(2, 4), Squared(3, 9) ) } @Parameter(0) lateinit var data: Squared @Test fun test() { assertEquals(data.expected, data.input * data.input) } } data class Squared( val input: Int, val expected: Int )
まずは、対象となるテストクラスに @RunWith(Parameterized::class)
を付けます。
次にテストデータを定義します。データに@Parameters
を付けます。ここはstaticにする必要があります。
渡されるデータを受け取りたい変数に@Parameter
を付けることでテスト実行時にテストデータが格納されます。
渡されるデータがIterator
の場合、@Parameter
の引数に数値を渡すことでそのIndexのデータを受け取れます。(デフォルトは0)
実行結果を見てみるとデータの分だけテストが実行されていることがわかります。
JUnit4のTheory
次は別の方法で@Theory
を使う方法
@RunWith(Theories::class) class SquaredTestJUnit4TheoryTest { companion object { @JvmStatic @DataPoints fun data() = listOf( Squared(1, 1), Squared(2, 4), Squared(3, 9) ) } @Theory fun test(data: Squared) { println("input: " + data.input + "expected: " + data.expected) Assert.assertEquals(data.expected, data.input * data.input) } }
こちらは、対象となるテストクラスに @RunWith(Theories::class)
を付けます。
渡すデータには@DataPoints
を付けます。この時もstaticにする必要があります。
テストメソッドには@Test
ではなく、@Theory
をつけます。
テストメソッドの引数には受け取るデータを指定します。(ここではSquared)
実行すると以下のような結果になります。
1つしか実行されてないように見えますが、printなどして確認して見るとちゃんとデータ分実行されています。(なんともわかりにくい)
Junit5のParameterizedTest
(これが一番よさげ) 上2つの方法はJUni4でしたが、JUnit5が使えるならこの方法がシンプルでいいです。
class SquaredTestJUnit5 { companion object { @JvmStatic fun squaredTestProvider(): Stream<Squared> = Stream.of( Squared(1, 1), Squared(2, 4), Squared(3, 9) ) } @ParameterizedTest @MethodSource("squaredTestProvider") fun test(data: Squared) { Assertions.assertEquals(data.expected, data.input * data.input) } }
渡すテストデータはStream<T>
で宣言でき渡したいデータをstaticな関数で定義します。
テストメソッドには@ParameterizedTest
を付けます。データには@MethodSource
を付けることで受け取れます。
(引数にテストデータを返す関数名を文字列で渡します。ここではsquaredTestProvider)
@MethodSource
のほかにも@ValueSource
や@CSVSource
などあります。
実行結果を見るとこのようになります。
参考
Parameterized tests · junit-team/junit4 Wiki · GitHub
Theories · junit-team/junit4 Wiki · GitHub
GitHub - mannodermaus/android-junit5: Testing with JUnit 5 for Android.