Migrating Groovy to Kotlin: afterTest

I’d like to migrate my Groovy plugin definition to Kotlin. For that, I’m unable to figure out how to convert the following snippet:

tasks.withType(Test).configureEach {
    afterTest { descriptor, result ->
        if (result.resultType == TestResult.ResultType.SKIPPED) {
            throw new GradleException("Do not ignore test cases")
        }
    }
}

The idea is to fail the build if at least one test is skipped/ignored, for example because assertJ’s assumeThat fails.

According to IntelliJ IDEA, the afterTest method exists, and I should provide a groovy.lang.Closure. This doesn’t seem right to me, as I’m using Kotlin, not Groovy.

The following seems to work, but I don’t quite understand what I’m doing here - and why it has to be that obtuse.

tasks.withType<Test>() {
    addTestListener(object : TestListener {
        override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {
            if (result.resultType == TestResult.ResultType.SKIPPED) {
                throw GradleException("Do not ignore test cases")
            }
        }

        override fun afterSuite(suite: TestDescriptor, result: TestResult) {}
        override fun beforeSuite(suite: TestDescriptor) {}
        override fun beforeTest(testDescriptor: TestDescriptor) {}
    })
}

For the same reason you should not use tasks.withType(Test) { ... } in Groovy, you shouldn’t use tasks.withType<Test>() { ... } in Kotlin (destroying task configuration avoidance for all test tasks).

That those methods do only have a Closure variant is surely a shortcoming you could request get fixed with a feature request.

But in the meantime, you can use KotlinClosure2 like:

tasks.withType<Test>().configureEach {
    afterTest(KotlinClosure2<TestDescriptor, TestResult, Unit>({ _, result ->
        if (result.resultType == TestResult.ResultType.SKIPPED) {
            throw GradleException("Do not ignore test cases")
        }
    }))
}
1 Like