What are the best practices for testing Gradle Scripts?
I currently unit test my ant scripts with antunit, but I\'m looking to migrate to Gradle. I can only find art
Gradle 3.x test Toolkit available! Please, check out userguide here: https://docs.gradle.org/current/userguide/test_kit.html
The correctness of the logic can then be verified by asserting the following, potentially in combination:
copy-pasted example:
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.gradle.testkit.runner.TaskOutcome.*;
public class BuildLogicFunctionalTest {
@Rule public final TemporaryFolder testProjectDir = new TemporaryFolder();
private File buildFile;
@Before
public void setup() throws IOException {
buildFile = testProjectDir.newFile("build.gradle");
}
@Test
public void testHelloWorldTask() throws IOException {
String buildFileContent = "task helloWorld {" +
" doLast {" +
" println 'Hello world!'" +
" }" +
"}";
writeFile(buildFile, buildFileContent);
BuildResult result = GradleRunner.create()
.withProjectDir(testProjectDir.getRoot())
.withArguments("helloWorld")
.build();
assertTrue(result.getOutput().contains("Hello world!"));
assertEquals(result.task(":helloWorld").getOutcome(), SUCCESS);
}
private void writeFile(File destination, String content) throws IOException {
BufferedWriter output = null;
try {
output = new BufferedWriter(new FileWriter(destination));
output.write(content);
} finally {
if (output != null) {
output.close();
}
}
}
}
As long as you apply the plugin groovy
and your tests sit under src/test/groovy
there's no additional configuration needed to run them. The same is true for BDD tests with Spock for example. If you want to read more about Gradle's testing capabilities check out the book Building and Testing with Gradle. It covers testing with JUnit, TestNG, Spock, Geb and EasyB.
I think what tom meant is a way to test his own written gradle tasks, right? If you have written a custom gradle task by extending DefaultTask and you put it in the buildSrc folder of your project, you can add a junit/spock/whatever based test class to test your task implementation. Gradles own build provides a good example for that. have a look at
https://github.com/gradle/gradle/blob/master/buildSrc/src/test/groovy/org/gradle/build/docs/dsl/source/ExtractDslMetaDataTaskTest.groovy
This is a spock specification, that tests the ExtractDslMetaDataTask which was specifically written for griddles own build. The ExtractDslMetaDataTask is located at:
https://github.com/gradle/gradle/blob/master/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/ExtractDslMetaDataTask.groovy
To add assertions to your build script "adhoc tasks" like your example above you can use the groovy power assertion.
an example: if you have a a very simple task like this in your script:
task writeFoo << {
file("$buildDir/foo.txt").text = "bar"
}
you can either modify the task itself to add an assertion:
task writeFoo << {
file("$buildDir/foo.txt").text = "bar"
assert file("$buildDir/foo.txt).isFile()
}
or you add a dedicated test task to your script
task testWriteFoo(dependsOn: writeFoo) << {
assert file("$buildDir/foo.txt).isFile()
assert file("$buildDir/foo.txt).text == "bar"
}
remember that you can use the full power of the groovy language in your build scripts.
There are plans to have an integrated testing toolkit in gradle to support build script authors on testing their custom build logic. have a look at:
http://forums.gradle.org/gradle/topics/testing_toolkit_for_custom_build_logic