TestParameterInjectorをKotlinで使う

はじめに

TestParameterInjectorという、Junit4でParameterized Testをいい感じに書けるライブラリがある。

github.com

READMEなどはJavaをターゲットに記述されているが、Kotlinでも使える。

Gradle + Kotlinで使う

適当にGradleのプロジェクトを作成する。build.gradleに以下を追加。

dependencies {
    testImplementation 'com.google.testparameterinjector:test-parameter-injector:1.4'
}

あとはREADMEに書いてあるコードをそのままKotlinで書けばOK

@RunWith(TestParameterInjector::class)
class SampleTestParameterInjector {

    @Test
    fun test(@TestParameter enabled: Boolean) {
        assertThat(enabled).isTrue()
    }
}

これだけでenabledtrue, falseの2パターンのテストが実行される。 今回は特に関係ないが、アサーションライブラリはTruthを利用している。

truth.dev

Booleanだけではなくenumも全パターン網羅してくれる。

また、

@Test
fun testCombination(
    @TestParameter isPhone: Boolean, 
    @TestParameter isAndroid: Boolean
){
    ...
}

このように書くと、isPhone(true, false) * isAndroid(true, false) 計4つのテストが実行される。

プロパティに対して@TestParameterを使う場合にはプロパティをlateinit varで宣言しておくと良さそうだ。

@TestParameter lateinit var value: MyEnum

enum class MyEnum {
    VALUE_A,
    VALUE_B,
    VALUE_C
}

valueVALUE_A, VALUE_B, VALUE_Cそれぞれの状態で、各テストケースが実行されるようになる。

@TestParametersというパラメータもあって、

@Test
@TestParameters(
    value = [
        "{age: 17, expectIsAdult: false}",  //  パターン1
        "{age: 22, expectIsAdult: true}"   //  パターン2
    ]
)
fun personIsAdult(age: Int, expectIsAdult: Boolean) {
    ...
}

これで2パターンのパラメータでテストが実行される。

なお、この@TestParemetersをつけたテストを実行した際に次のようなエラーが発生する場合がある。

ava.lang.IllegalStateException: No parameter name could be found for public final void SampleTestParameterInjector.personIsAdult(int,boolean), which likely means that parameter names aren't available at runtime. Please ensure that the this test was built with the -parameters compiler option.

-parametersオプションが必要らしいので、build.gradleに以下を追加する。

gradle.projectsEvaluated {
    tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
        kotlinOptions.freeCompilerArgs += ['-java-parameters']
    }
}

こちらのRedditのスレッドが参考になった。

A few tips for TestParameterInjector Library : androiddev