Gradle's Unit Testing
Gradle's unit testing allows execution of test classes (e.g., those created using the JUnit library).
In this tutorial you will learn how to run a test class created using a JUnit library in Gradle.
Prerequisite:
You are required to do the JUnit Basics Tutorial.
You are required to do the Gradle's Dependency Management Tutorial.
Copy Sample Codes from Git repository
Open a terminal window and create the directory
gradletempin the root directory. Go to the created directory.> mkdir gradletemp > cd gradletempClone the git repository
https://github.com/pong-pantola/gradle-unit-testing.gitand go to the createdgradle-unit-testingdirectory.> git clone https://github.com/pong-pantola/gradle-unit-testing.git > cd gradle-unit-testingThe
gradle-unit-testingdirectory has a subdirectorysrc.gradle-unit-testing/ | |----build.gradle | |----src/ | |----main/ | | | |----java/net/tutorial/ | | | | | |----Math.java | | |----Calculator.java | | | |----resources/ | | | |----log4j.properties | |----test/ | |----java/net/tutorial/ | |----MyTest.java |----TestRunner.javasrchas subdirectoriesmainandtest.src/maincontains exactly the same files and subdirectories as the one in Gradle's Dependency Management Tutorial.src/testcontains exactly the same files and subidrectories as the one in JUnit Basics Tutorial.gradle-unit-testinghas a Gradle build scriptbuild.gradle. Its contents are those that were discussed in Gradle's Dependency Management Tutorial. Specifically, it defines Maven as a repository as well as the Log4j library dependency.In this tutorial,
build.gradlewill be updated to include entries related to unit testing.
Review the Java classes and Build script
Math.javacontains the methodsadd,sub, andmultiply. This is exactly the same file that was discussed in JUnit Basics Tutorial.Remember that the method
addhas a logical error (i.e., instead ofa+b;, the return statement isa-b;).In addition, a delay is inserted in the method
multiplyto demonstrate the timeout mechanism of JUnit.Calculator.javais exactly the same file that was discussed in Gradle's Dependency Management Tutorial. It is a Java application that usesMath.java.Recall that
Caculator.javauses the Log4j library:import org.apache.log4j.Logger;build.gradlehas the same content as the one you created in Gradle's Dependency Management Tutorial.Please review the text below for the current content of
build.gradle:apply plugin: 'java' repositories { mavenCentral() } dependencies { compile 'log4j:log4j:1.2.17' } jar { from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } manifest { attributes 'Main-Class': 'net.tutorial.Calculator' } }Note that the contents are related to repositories and dependencies related Log4j library since the
build.gradlefile was used in the Gradle's Dependency Management Tutorial.In this tutorial, entries related to testing will be added to
build.gradle.MyTest.javais exactly the same file that was discussed in JUnit Basics Tutorial. It serve as the test class to test the methods ofMath.java.Remember that
MyTest.javauses the JUnit library:import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test;You will observe later if the use of the JUnit libary has an effect in Gradle later.
TestRunner.javais an application that runs the test methods found inMyTest.java.Like
MyTest.java,TestRunner.javauses the JUnit library:import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;Compile
.javafiles using Gradle'sassembletask.> gradle assembleRecall that in the Gradle's Dependency Management Tutorial, it was mentioned that instead of
assembletask, you may use theclassestask (i.e.,gradle classes) to compile the.javaclasses followed by thejartask (gradle jar) to create the.jarfile.assemble task=classestask +jartaskOutput:
:compileJava :processResources :classes :jar :assemble BUILD SUCCESSFUL Total time: 8.285 secsAs expected, compilation is successful.
The subdirectory
buildis automatically created. Below are some of the subdirectories and files that are insidebuild.gradle-unit-testing/ | |----build/ | |----classes/main | | | |----net/tutorial/ | | | |----Math.class | |----Calculator.class | |----libs/ | | | |----gradle-dependency-management.jar | |----resources/main/ | |----log4j.propertiesNotice that the
Math.classandCalculator.classwere created after theassembletask.However the corresponding
.classfiles ofMyTest.javaandTestRunner.javaare not created.When the
assembletask is used, only the files under the subdirectorysrc/mainare considered. BothMath.javaandCalculator.javaare under this subdirectory.However,
MyTest.javaandTestRunner.javaare under the subdirectorysrc/test. Therefore, these files are excluded from theassembletask.
Compile classes under the Subdirectory src/test
To compile the
.javafiles under the subdirectorysrc/test, use the `testClasses' task.Make sure that you are in the gradle-unit-testing directory before issuing the command below.
> gradle testClassesOutput:
/gradletemp/experiment/gradle-unit-testing/src/test/java/net/tutorial/MyTest.java:3: error: package org.junit does not exist import static org.junit.Assert.assertEquals; ^ TUTORIAL NOTE: Other lines in this error message are omitted /gradletemp/experiment/gradle-unit-testing/src/test/java/net/tutorial/TestRunner.java:3: error: package org.junit.runner does not exist import org.junit.runner.JUnitCore; ^ TUTORIAL NOTE: Other lines in this error message are omitted /gradletemp/experiment/gradle-unit-testing/src/test/java/net/tutorial/MyTest.java:10: error: cannot find symbol @Before ^ symbol: class Before location: class MyTest TUTORIAL NOTE: Other lines in this error message are omitted /gradletemp/experiment/gradle-unit-testing/src/test/java/net/tutorial/TestRunner.java:9: error: cannot find symbol Result result = JUnitCore.runClasses(MyTest.class); ^ symbol: class Result location: class TestRunner TUTORIAL NOTE: Other lines in this error message are omitted 17 errors :compileTestJava FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':compileTestJava'. > Compilation failed; see the compiler error output for details. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. BUILD FAILED Total time: 6.224 secsA compilation error due to JUnit dependency is encountered. Let's fix this problem by utlizing the dependency management you learned in Gradle's Dependency Management Tutorial.
Specify the JUnit library in build.gradle by adding the
testCompile 'junit:junit:4.11'line as shown below:apply plugin: 'java' repositories { mavenCentral() } dependencies { compile 'log4j:log4j:1.2.17' testCompile 'junit:junit:4.12' } jar { from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } manifest { attributes 'Main-Class': 'net.tutorial.Calculator' } }Take note that the
dependenciessection ofbuild.gradleis updated to the following:dependencies { compile 'log4j:log4j:1.2.17' testCompile 'junit:junit:4.12' }and NOT to the following approach:
dependencies { compile 'log4j:log4j:1.2.17', 'junit:junit:4.12' }If the latter approach is used (i.e.,
compile 'log4j:log4j:1.2.17', 'junit:junit:4.12'), the JUnit library becomes available toMath.javaandCalculator.java(i.e., files in the subdirectorysrc/main). Since JUnit is not used byMath.javaandCalculator.java, thetestCompile 'junit:junit:4.12'is better.In this tutorial, we used
'junit:junit:4.12'. In Gradle's Dependency Management Tutorial, it was discusssed that the dependency entry uses the following format:'group:name:version'.To know how
'junit:junit:4.12'was derived, you may go to the Maven Central Repository. In the search box, typejunit. For this tutorial, the row that was selected is the one with the following values:GroupId ArtifactId Latest Vesion junit junit 4.12 Compile again the
.javafiles under the subdirectorysrc/test, use the `testClasses' task.> gradle testClassesOutput:
:compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :compileTestJava Download https://repo1.maven.org/maven2/junit/junit/4.12/junit-4.12.pom Download https://repo1.maven.org/maven2/junit/junit/4.12/junit-4.12.jar :processTestResources UP-TO-DATE :testClasses BUILD SUCCESSFUL Total time: 1 mins 38.426 secsAs expected, the compilation error due to JUnit dependency is resolved.
The subdirectory
build/classesnow contains the subdirectorytest:gradle-unit-testing/ | |----build/classes/ | |----main/ | | | |----net/tutorial/ | | | |----Math.class | |----Calculator.class | |----test/ | |----net/tutorial/ | |----MyTest.class |----TestRunner.class
Run the Test
To run the test, use the `test' task.
Make sure that you are in the gradle-unit-testing directory before issuing the command below.
> gradle testOutput:
:compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :compileTestJava UP-TO-DATE :processTestResources UP-TO-DATE :testClasses UP-TO-DATE :test net.tutorial.MyTest > multiplyShouldReturnProduct FAILED org.junit.runners.model.TestTimedOutException at MyTest.java:27 net.tutorial.MyTest > addShouldReturnSum FAILED java.lang.AssertionError at MyTest.java:17 3 tests completed, 2 failed :test FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':test'. > There were failing tests. See the report at: file:///D:/gradletemp/experiment/gradle-unit-testing/build/reports/tests/index.html * Try: Run with --stacktrace option to get the stack trace. Run with --info o option to get more log output. BUILD FAILED Total time: 7.645 secsAs expected, the
multiplyShouldReturnProducttest method resulted to an error since themultiplymethod ofMath.javahas a call to thedelaymethod which produces a 3 sec. delay. This is way longer than the 1 sec. timeout that is indicated in the annotation in the test method (i.e.,@Test(timeout=1000)).In addition, the
addShouldReturnSumtest method also failed since we intentionally made thesummethod ofMath.javaincorrect. Recall that we usedreturn a-b;instead ofreturn a+b;in thesummethod ofMath.java.Fix the error in
Math.javaby updating theaddandmultiplymethods.Change the
addmethod by changinga-btoa+b:public int add(int a, int b){ return a+b; }Change the
multiplymethod by commenting outdelay():public int multiply(int a, int b){ //added to simulate that this method is //taking too long to execute //delay(); return a*b; }Run the test again.
> gradle testOutput:
:compileJava :processResources UP-TO-DATE :classes :compileTestJava :processTestResources UP-TO-DATE :testClasses :test BUILD SUCCESSFUL Total time: 7.322 secsThe errors are now fixed.
End of Tutorial
Go back to the List of Tutorials.
