This tutorial assumes that you have Java installed on your system.
For more on installing Java and setting up your classpath see the YoLinux.com Java tutorial.
Download a prebuilt JUnit jar file: http://www.junit.org eg. junit-4.9b2.jar
Place the JUnit jar file where accessible: (examples)
- Linux: /opt/java/lib/ or /usr/java/latest/lib/
- MS/Windows: C:\Java\lib\ or C:\Program Files\Java\jdk1.6.0_26\lib\
Add the JUnit jar file to your Java class path (environment variable or set in ant build script).
In this tutorial we will be using an ANT build script.
The build path used in this example is as follows:
ProjectX/build.xml /src/com/megacorp/projx/util/Addition.java | /Multiply.java /test/src/com/megacorp/projx/JUnit/AllTests.java /test/src/com/megacorp/projx/util/Addition_Test.java | | /Multiply_Test.java | /htmlreports/index.html (generated by JUnit) | | /com/megacorp/projx/JUnit/ (unit test reports end up here) / /data/TEST-com.megacorp.projx.JUnit.AllTests.xml (generated by JUnit)Notes:
- JUnit can generate reports in various formats. HTML reports are directly viewable in a browser with links to the individual reports. XML output is often used as an iinterface with other systems like Jenkins.
- The unit test source mimics the source tree and class names.
Example Java Class to Test:
-
File: src/com/megacorp/projx/util/Addition.java
01
package
com.megacorp.projx.util;
02
03
import
java.text.*;
04
05
public
class
Addition
06
{
07
08
public
static
int
twoValues(
int
x,
int
y)
09
{
10
return
x + y;
11
}
12
}
01
package
com.megacorp.projx.util;
02
03
import
java.text.*;
04
05
public
class
Multiply
06
{
07
08
public
static
int
twoValues(
int
x,
int
y)
09
{
10
return
x * y;
11
}
12
}
JUnit unit test source:
- Class to specify tests to run: AllTests.java
- Classes to perform the unit tests:
- Addition_Test.java
- Multiply_Test.java
-
File: test/src/com/megacorp/projx/JUnit/AllTests.java
01
package
com.megacorp.projx.JUnit;
02
03
import
org.junit.runner.RunWith;
04
import
org.junit.runners.Suite;
05
06
import
com.megacorp.projx.util.Addition_Test;
07
import
com.megacorp.projx.util.Multiply_Test;
08
09
@RunWith
(Suite.
class
)
10
@Suite
.SuiteClasses({Addition_Test.
class
,Multiply_Test.
class
})
11
public
class
AllTests
12
{
13
// Empty, since the annotations include all of the necessary configuration
14
}
01
package
com.megacorp.projx.util;
02
03
import
java.io.IOException;
04
import
java.io.PrintWriter;
05
import
junit.framework.TestCase;
06
import
com.megacorp.projx.util.Addition;
07
import
com.megacorp.projx.util.Multiply;
08
09
public
class
Addition_Test
extends
TestCase
10
{
11
private
int
x =
0
;
12
private
int
y =
0
;
13
14
// Stuff to do before test
15
protected
void
setUp()
16
{
17
x =
4
;
18
y =
5
;
19
}
20
21
// Stuff to do after test
22
protected
void
tearDown()
23
{
24
x =
0
;
25
y =
0
;
26
}
27
28
public
void
testAddition()
29
{
30
System.out.println(
"Test use of Addition class"
);
31
32
int
z = Addition.twoValues(x,y);
33
System.out.println(
" Result: "
+ z);
34
35
assertEquals(
9
,z);
// The test
36
}
37
}
01
package
com.megacorp.projx.util;
02
03
import
java.io.IOException;
04
import
java.io.PrintWriter;
05
import
junit.framework.TestCase;
06
import
com.megacorp.projx.util.Addition;
07
import
com.megacorp.projx.util.Multiply;
08
09
public
class
Multiply_Test
extends
TestCase
10
{
11
private
int
x =
0
;
12
private
int
y =
0
;
13
14
protected
void
setUp()
15
{
16
x =
4
;
17
y =
5
;
18
}
19
20
protected
void
tearDown()
21
{
22
x =
0
;
23
y =
0
;
24
}
25
26
public
void
testMultiply()
27
{
28
System.out.println(
"Test use of Multiply class"
);
29
30
int
z = Multiply.twoValues(x,y);
31
System.out.println(
" Result: "
+ z);
32
33
assertEquals(
20
,z);
34
}
35
}
Ant file to compile and run a JUnit test:
File: ./build.xml01
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
02
<
project
name
=
"projx"
default
=
"all"
basedir
=
"."
>
03
<
description
>Builds, tests, and runs projx</
description
>
04
<
property
name
=
"build.dir"
value
=
"./"
/>
05
<
property
name
=
"src.dir"
location
=
"${build.dir}/src"
/>
06
<
property
name
=
"test.dir"
location
=
"${build.dir}/test/src"
/>
07
<
property
name
=
"test.htmlreports.dir"
location
=
"${build.dir}/test/htmlreports"
/>
08
<
property
name
=
"test.data.dir"
location
=
"${build.dir}/test/data"
/>
09
<
property
name
=
"junit.class.name"
value
=
"com.megacorp.projx.JUnit.AllTests"
/>
10
11
<!-- Classpath to find java packages -->
12
<
path
id
=
"classpath.base"
>
13
<
pathelement
location
=
"/usr/java/latest/lib/tools.jar"
/>
14
</
path
>
15
16
<!-- Classpath for tests to find src packages -->
17
<
path
id
=
"classpath.src"
>
18
<
pathelement
location
=
"src"
/>
19
</
path
>
20
21
<
path
id
=
"classpath.junittest"
>
22
<
path
refid
=
"classpath.base"
/>
23
<
pathelement
location
=
"/opt/java/lib/junit-4.9b2.jar"
/>
24
<
pathelement
location
=
"${test.dir}"
/>
25
</
path
>
26
27
<
target
name
=
"clean"
description
=
"Remove all .class files"
>
28
<
delete
includeEmptyDirs
=
"true"
failonerror
=
"false"
>
29
<
fileset
dir
=
"${src.dir}"
>
30
<
include
name
=
"**/*.class"
/>
31
</
fileset
>
32
<
fileset
dir
=
"${test.dir}"
>
33
<
include
name
=
"**/*.class"
/>
34
</
fileset
>
35
<
fileset
dir
=
"${test.htmlreports.dir}"
>
36
<
include
name
=
"**/*.txt"
/>
37
<
include
name
=
"**/*.xml"
/>
38
<
include
name
=
"**/*.html"
/>
39
</
fileset
>
40
</
delete
>
41
</
target
>
42
43
<
target
name
=
"compile"
>
44
<
javac
srcdir
=
"${src.dir}"
destdir
=
"${src.dir}"
debug
=
"true"
includeAntRuntime
=
"false"
>
45
<
classpath
refid
=
"classpath.base"
/>
46
<
include
name
=
"**/*.java"
/>
47
</
javac
>
48
</
target
>
49
50
<
target
name
=
"compile-test"
depends
=
"compile"
>
51
<
javac
srcdir
=
"${test.dir}"
destdir
=
"${test.dir}"
debug
=
"true"
includes
=
"${src.dir}"
includeAntRuntime
=
"false"
>
52
<
classpath
refid
=
"classpath.base"
/>
53
<
classpath
refid
=
"classpath.src"
/>
54
<
classpath
refid
=
"classpath.junittest"
/>
55
<
include
name
=
"**/*.java"
/>
56
</
javac
>
57
</
target
>
58
59
<
target
name
=
"test"
depends
=
"compile-test"
>
60
<
mkdir
dir
=
"${test.data.dir}"
/>
61
<
mkdir
dir
=
"${test.htmlreports.dir}"
/>
62
<
junit
fork
=
"no"
haltonfailure
=
"no"
showoutput
=
"yes"
printsummary
=
"true"
>
63
<
test
name
=
"${junit.class.name}"
todir
=
"${test.data.dir}"
/>
64
<
formatter
type
=
"brief"
usefile
=
"false"
/>
65
<
formatter
type
=
"xml"
/>
66
<
classpath
refid
=
"classpath.base"
/>
67
<
classpath
refid
=
"classpath.src"
/>
68
<
classpath
refid
=
"classpath.junittest"
/>
69
</
junit
>
70
<
junitreport
todir
=
"${test.htmlreports.dir}"
>
71
<
fileset
dir
=
"${test.data.dir}"
>
72
<
include
name
=
"TEST-*.xml"
/>
73
</
fileset
>
74
<
report
format
=
"frames"
todir
=
"${test.htmlreports.dir}"
/>
75
</
junitreport
>
76
</
target
>
77
78
<
target
name
=
"all"
depends
=
"compile-test"
/>
79
80
</
project
>
- Build: ant
- Test: ant test
[bash JUnit]$ ant clean Buildfile: /home/user1/JUnit/build.xml clean: BUILD SUCCESSFUL Total time: 0 seconds [bash JUnit]$ ant test Buildfile: /home/user1/JUnit/build.xml compile: [javac] Compiling 2 source files to /home/user1/JUnit/src compile-test: [javac] Compiling 3 source files to /home/user1/JUnit/test/src test: [junit] Running com.megacorp.projx.JUnit.AllTests [junit] Testsuite: com.megacorp.projx.JUnit.AllTests [junit] Test use of Addition class [junit] Result: 9 [junit] Test use of Multiply class [junit] Result: 20 [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.019 sec [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.019 sec [junit] [junit] ------------- Standard Output --------------- [junit] Test use of Addition class [junit] Result: 9 [junit] Test use of Multiply class [junit] Result: 20 [junit] ------------- ---------------- --------------- [junitreport] Processing /home/user1/JUnit/test/htmlreports/TESTS-TestSuites.xml to /tmp/null1813236 [junitreport] Loading stylesheet jar:file:/opt/apache-ant-1.8.2/lib/ant-junit.jar ! /org/apache/tools/ant/taskdefs/optional/junit/xsl/junit-frames.xsl [junitreport] Transform time: 315ms [junitreport] Deleting: /tmp/null1813236 BUILD SUCCESSFUL Total time: 1 second
-
View JUnit results with browser by opening file ./test/htmlreports/index.html
ConfigurationFor more, see the YoLinux.com Tutorials Jenkins installation and configuration and Jenkins Plugins for Java
Using Maven to build your project and JUnit tests will define the directory paths used and the Jenkins configuration. Unlike Ant which explicitly directs the build and test process, Maven implicitly controls the process using its own conventions including the directory paths used to place your code.
ProjectX/pom.xml /src/main/java/com/megacorp/projx/util/Addition.java | /Multiply.java /src/test/java/com/megacorp/projx/JUnit/AllTests.java /src/test/java/com/megacorp/projx/util/Addition_Test.java | | /Multiply_Test.java
01
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
02
<
project
xmlns
=
"http://maven.apache.org/POM/4.0.0"
03
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
04
xsi:schemaLocation
=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
05
06
<
modelVersion
>4.0.0</
modelVersion
>
07
<
name
>JUnit Test Example POM</
name
>
08
<
groupId
>com.megacorp.projectx</
groupId
>
09
<
artifactId
>ProjectX</
artifactId
>
10
<
version
>1.0.0</
version
>
11
<
packaging
>jar</
packaging
>
12
13
<
build
>
14
<
plugins
>
15
<
plugin
>
16
<
groupId
>org.apache.maven.plugins</
groupId
>
17
<
artifactId
>maven-surefire-plugin</
artifactId
>
18
<
version
>2.20</
version
>
19
<
configuration
>
20
<
redirectTestOutputToFile
>true</
redirectTestOutputToFile
>
21
</
configuration
>
22
</
plugin
>
23
</
plugins
>
24
</
build
>
25
26
<
properties
>
27
<
maven.compiler.source
>1.8</
maven.compiler.source
>
28
<
maven.compiler.target
>1.8</
maven.compiler.target
>
29
<
maven.jar.plugin
>2.3.2</
maven.jar.plugin
>
30
<
project.build.sourceEncoding
>UTF-8</
project.build.sourceEncoding
>
31
<
junit.version
>4.12</
junit.version
>
32
</
properties
>
33
34
<
dependencies
>
35
<
dependency
>
36
<
groupId
>junit</
groupId
>
37
<
artifactId
>junit</
artifactId
>
38
<
version
>${junit.version}</
version
>
39
<
scope
>test</
scope
>
40
</
dependency
>
41
</
dependencies
>
42
43
</
project
>
Maven Target Description validate validate the project is correct and all necessary information is available compile compile the source code of the project test test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed package take the compiled code and package it in its distributable format, such as a JAR. verify run any checks on results of integration tests to ensure quality criteria are met install install the package into the local repository, for use as a dependency in other projects locally deploy done in the build environment, copies the final package to the remote repository for sharing with other developers and projects. The target is inclusive of all prior to it. Thus "mvn install" will execute targets alidate, compile, package, verify and install.
Build the project: mvn install
Note that Maven downloads all maven and build dependancies and will take a while on the first build (thus an internet connection will be required). Dependencies will be downloaded and stored in ~/m2/...ProjectX/target/ProjectX-1.0.0.jar |target/surefire-reports/... xml (test results)
Configure Jenkins:
Configure Jenkins to use your Maven installation. Select "Jenkins" + "Global Tool Configuration":
Configure Build Project:
Use the Jenkins Maven plug-in rather than executing Maven as a shell command. The Maven plug-in is Maven aware and will post-process JUnit results for use with Jenkins. Select your Jenkins project and "Configure":
Configure Build Project JUnit reporting:
Test results will be put into the following directory structure:
For more on Jenkins, see the YoLinux tutorial on Jenkins and Java
For more on Maven, see the YoLinux tutorial on building Java applications with Maven
- JUnit Home Page
- Apache Ant - build tool
- javac man page