Android
Kotlin
gradle
Spek
junit5

android-junit5+Spekの設定で詰まったのでメモ

AndroidのライブラリのテストをSpekで作りたくてandroid-junit5使ったけど割とGradleのスクリプト書く時に詰まった話。
使ってるGradleのバージョン4.6です。

だいたいの記事でこんな感じになってる

ルートディレクトリのgradle.build
buildscript {
    ext.kotlin_version = '1.2.41'

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.0-alpha14'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "de.mannodermaus.gradle.plugins:android-junit5:1.0.32"
    }
}


allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

テストしたいモジュールのgradle.build
apply plugin: "com.android.library"
apply plugin: "kotlin-android"
apply plugin: "de.mannodermaus.android-junit5"

android {
    compileSdkVersion 27

    defaultConfig {
        minSdkVersion 23
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }



    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
        test.java.srcDirs += 'src/test/kotlin'
    }
}

junitPlatform {
    filters {
        engines {
            include 'spek'
        }
    }
}

dependencies {
    //kotlin
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

    //spek
    testImplementation "org.jetbrains.spek:spek-junit-platform-engine:$spek_ver"
    testImplementation "org.jetbrains.spek:spek-api:$spek_ver"

    //test
    testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}

まぁこの通りに動かない、junitPlatform()なんてメソッドは無いと怒られる。悲しい。
すくなくともAndroidStudio3.2では怒られます。

android-junit5のwikiのConfiguration DSLを見に行くとそもそもDSLが違った…

書き換えたテストしたいモジュールのgradle.buildがこれ

テストしたいモジュールのgradle.build
apply plugin: "com.android.library"
apply plugin: "kotlin-android"
apply plugin: "de.mannodermaus.android-junit5"

android {
    compileSdkVersion 27

    defaultConfig {
        minSdkVersion 23
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }



    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }

    testOptions.junitPlatform {
        filters {
            includeClassNamePatterns '.*Spek'
            engines.include 'spek'
        }       
    }
}

dependencies {
    //kotlin
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

    //spek
    testImplementation "org.jetbrains.spek:spek-junit-platform-engine:$spek_ver"
    testImplementation "org.jetbrains.spek:spek-api:$spek_ver"

    //test
    testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}

とりあえずこれでテストは動きました。
テストリザルトがXMLで出力されるのでついでにをれをHTMLに変換するサンプルおいときます。

テストしたいモジュールのgradle.build
apply plugin: "com.android.library"
apply plugin: "kotlin-android"
apply plugin: "de.mannodermaus.android-junit5"

android {
    ....
}

dependencies {
    ....
}


//junit report, xml to html

configurations {
    junitXmlToHtml
}

dependencies {
    junitXmlToHtml 'org.apache.ant:ant-junit:1.10.3'
}

gradle.taskGraph.whenReady { taskGraph ->
    def junitPlatformTest = ":テストしたいモジュールの名前:test"
    if (!taskGraph.hasTask(junitPlatformTest)) return
    taskGraph.allTasks.find { it.name == "test" }.doLast {
        def reportsDirPath = "$buildDir/test-reports"
        (new File(reportsDirPath)).mkdirs()

        ant.taskdef(name: 'junitReport',
                classname: 'org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator',
                classpath: configurations.junitXmlToHtml.asPath)

        ["debug", "release"].forEach { dirName ->
            def xmlReportDir = "$buildDir/test-results/$dirName/junit-platform"
            ant.junitReport(todir: xmlReportDir, tofile: "aggregated-test-results.xml") {
                fileset(dir: xmlReportDir)
                def dir = new File("$reportsDirPath/$dirName/")
                dir.mkdirs()
                report(format: 'noframes', todir: dir)
            }
        }
    }
}

Spek使ってるとHTMLが微妙なかんじだけどまぁXMLよりはマシです。
なんかいい感じにHTMLで出力する方法無いかな…