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
gradletemp
in the root directory. Go to the created directory.> mkdir gradletemp > cd gradletemp
Clone the git repository
https://github.com/pong-pantola/gradle-unit-testing.git
and go to the createdgradle-unit-testing
directory.> git clone https://github.com/pong-pantola/gradle-unit-testing.git > cd gradle-unit-testing
The
gradle-unit-testing
directory 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.java
src
has subdirectoriesmain
andtest
.src/main
contains exactly the same files and subdirectories as the one in Gradle's Dependency Management Tutorial.src/test
contains exactly the same files and subidrectories as the one in JUnit Basics Tutorial.gradle-unit-testing
has 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.gradle
will be updated to include entries related to unit testing.
Review the Java classes and Build script
Math.java
contains the methodsadd
,sub
, andmultiply
. This is exactly the same file that was discussed in JUnit Basics Tutorial.Remember that the method
add
has a logical error (i.e., instead ofa+b
;, the return statement isa-b;
).In addition, a delay is inserted in the method
multiply
to demonstrate the timeout mechanism of JUnit.Calculator.java
is exactly the same file that was discussed in Gradle's Dependency Management Tutorial. It is a Java application that usesMath.java
.Recall that
Caculator.java
uses the Log4j library:import org.apache.log4j.Logger;
build.gradle
has 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.gradle
file was used in the Gradle's Dependency Management Tutorial.In this tutorial, entries related to testing will be added to
build.gradle
.MyTest.java
is 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.java
uses 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.java
is an application that runs the test methods found inMyTest.java
.Like
MyTest.java
,TestRunner.java
uses the JUnit library:import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
Compile
.java
files using Gradle'sassemble
task.> gradle assemble
Recall that in the Gradle's Dependency Management Tutorial, it was mentioned that instead of
assemble
task, you may use theclasses
task (i.e.,gradle classes
) to compile the.java
classes followed by thejar
task (gradle jar
) to create the.jar
file.assemble task
=classes
task +jar
taskOutput:
:compileJava :processResources :classes :jar :assemble BUILD SUCCESSFUL Total time: 8.285 secs
As expected, compilation is successful.
The subdirectory
build
is 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.properties
Notice that the
Math.class
andCalculator.class
were created after theassemble
task.However the corresponding
.class
files ofMyTest.java
andTestRunner.java
are not created.When the
assemble
task is used, only the files under the subdirectorysrc/main
are considered. BothMath.java
andCalculator.java
are under this subdirectory.However,
MyTest.java
andTestRunner.java
are under the subdirectorysrc/test
. Therefore, these files are excluded from theassemble
task.
Compile classes under the Subdirectory src/test
To compile the
.java
files 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 testClasses
Output:
/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 secs
A 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
dependencies
section ofbuild.gradle
is 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.java
andCalculator.java
(i.e., files in the subdirectorysrc/main
). Since JUnit is not used byMath.java
andCalculator.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
.java
files under the subdirectorysrc/test
, use the `testClasses' task.> gradle testClasses
Output:
: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 secs
As expected, the compilation error due to JUnit dependency is resolved.
The subdirectory
build/classes
now 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 test
Output:
: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 secs
As expected, the
multiplyShouldReturnProduct
test method resulted to an error since themultiply
method ofMath.java
has a call to thedelay
method 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
addShouldReturnSum
test method also failed since we intentionally made thesum
method ofMath.java
incorrect. Recall that we usedreturn a-b;
instead ofreturn a+b;
in thesum
method ofMath.java
.Fix the error in
Math.java
by updating theadd
andmultiply
methods.Change the
add
method by changinga-b
toa+b
:public int add(int a, int b){ return a+b; }
Change the
multiply
method 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 test
Output:
:compileJava :processResources UP-TO-DATE :classes :compileTestJava :processTestResources UP-TO-DATE :testClasses :test BUILD SUCCESSFUL Total time: 7.322 secs
The errors are now fixed.
End of Tutorial
Go back to the List of Tutorials.