-
Notifications
You must be signed in to change notification settings - Fork 20
TestKit DSL
The TestKit DSL provides a new abstraction over Gradle TestKit which is usable in Java, Groovy, and Kotlin, and can be used with any unit testing framework. It assists in setting up a sample project, with an API that makes the structure of the project easily understandable to the reader of the test. This implementation is in an MVP state, with more functionality planned to cover common use cases.
The project builder assists with authoring the files of a Gradle project in a temporary directory. The result of the project builder is a TestProjectRunner, which will be covered in the next section.
Example (Kotlin + JUnit Jupiter):
internal class KotlinDslTest {
@TempDir
lateinit var testProjectDir: File
fun `test single project build with sources`() {
val runner = testProject(testProjectDir) {
rootProject {
plugins {
java()
}
src {
main {
java("Main.java") {
// language=java
"""
public class Main {
public static void main(String[] args) {
}
}
"""
}
}
}
}
}
}
}The TestProjectRunner allows you to invoke the Gradle TestKit runner, with options, on your project. This is just a very thin wrapper around the TestKit GradleRunner that provides more ideomatic syntax for Groovy and Kotlin and handles setting the correct project directory for you. All options of the TestKit GradleRunner are exposed through the invocation DSL. The result is a TestKit BuildResult.
Example:
val result = runner.run("build") {
forwardOutput()
withGradleVersion("9.0.0")
}This library also provides custom AssertJ assertions for the BuildResult. These can be used in Java, Kotlin, or Groovy, as long as you are using AssertJ.
Example:
assertThat(result)
.hasNoDeprecationWarnings()
.hasNoMutableStateWarnings()
assertThat(result).task(":compileJava").hasOutcome(TaskOutcome.SUCCESS)
assertThat(result).task(":build").hasOutcome(TaskOutcome.SUCCESS)Unlike the Spock helpers, the TestKit DSL does not manage the temporary project directory. This is outside the abstraction so that it can be delegated to the helper for whichever test framework is being used. If you would like the project directory to be in the project build directory, and not cleaned up after the test run, this can be done using your test framework. For example, Junit5 has the TempDirFactory interface that you can use with a meta-annotation to achieve this effect. Example.
Example (Groovy + Spock):
class GroovyDslSpockTest extends Specification {
@TempDir
File testProjectDir
@Unroll
void "test groovy DSL with spock"() {
setup:
final var runner = GroovyTestProjectBuilder.testProject(testProjectDir) {
settings {
plugins {
id("org.gradle.toolchains.foojay-resolver-convention").version("0.10.0")
}
}
rootProject {
plugins {
java()
}
javaToolchain(javaVersion)
src {
main {
java("Main.java") {
// language=java
"""
public class Main {
public static void main(String[] args) {
}
}
"""
}
}
}
}
}
when:
final var result = runner.run(["build"]) {
withGradleVersion(gradle.version)
forwardOutput()
}
then:
assertThat(result)
.hasNoDeprecationWarnings()
.hasNoMutableStateWarnings()
assertThat(result).task(":compileJava").hasOutcome(TaskOutcome.SUCCESS)
assertThat(result).task(":build").hasOutcome(TaskOutcome.SUCCESS)
where:
javaVersion | gradle
11 | SupportedGradleVersion.MIN
17 | SupportedGradleVersion.MAX
}
}