JUnit Tutorial For Unit Testing2
JUnit Tutorial For Unit Testing2
JUnit Tutorial
JUnit Tutorial ii
Contents
2 JUnit introduction 2
2.1 JUnit Simple Example using Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 JUnit annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 JUnit assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5 Conclusions 26
JUnit Tutorial iii
Preface
We have provided plenty of JUnit [1] tutorials here at Java Code Geeks, like JUnit Getting Started Example [2], JUnit Using
Assertions and Annotations Example [3], JUnit Annotations Example [4] and so on.
However, we prefered to gather all the JUnit features in one detailed guide for the convenience of the reader.
We hope you like it!
References:
[1] http://junit.org/
[2] http://examples.javacodegeeks.com/core-java/junit/junit-getting-started-example/
[3] http://examples.javacodegeeks.com/core-java/junit/junit-using-assertions-and-annotations-example/
[4] http://examples.javacodegeeks.com/core-java/junit/junit-annotations-example/
JUnit Tutorial v
Konstantina has graduated from the Department of Informatics and Telecommunications in National and Kapodistrian University
of Athens (NKUA) and she is currently pursuing M.Sc studies in Advanced Information Systems at the same department. She is
also working as a research associate for NKUA in the field of telecommunications. Her main interests lie in software engineering,
web applications, databases and telecommunications.
JUnit Tutorial 1 / 26
Chapter 1
A unit can be a function, a class, a package, or a subsystem. So, the term unit testing refers to the practice of testing such small
units of your code, so as to ensure that they work as expected. For example, we can test whether an output is what we expected
to see given some inputs or if a condition is true or false.
This practice helps developers to discover failures in their logic behind their code and improve the quality of their code. Also,
unit testing can be used so as to ensure that the code will work as expected in case of future changes.
In general, the development community has different opinion regarding the percentage of code that should be tested (test cover-
age). Some developers believe that the code should have 100% test coverage, while others are comprised with a test coverage of
50% or less. In any case, you should write tests for complex or critical parts of your code.
The most popular testing framework in Java is JUnit. As this guide is focused to JUnit, more details for this testing framework
will presented in the next sections. Another popular testing framework in Java is TestNG.
JUnit Tutorial 2 / 26
Chapter 2
JUnit introduction
JUnit is an open source testing framework which is used to write and run repeatable automated tests, so that we can be ensured
that our code works as expected. JUnit is widely used in industry and can be used as stand alone Java program (from the command
line) or within an IDE such as Eclipse.
JUnit provides:
• an entire object
• part of an object - a method or some interacting methods
• interaction between several objects
In this section we will see a simple JUnit example. First we will present the class we would like to test:
Calculate.java
package com.javacodegeeks.junit;
In the above source code, we can notice that the class has one public method named sum(), which gets as inputs two integers,
adds them and returns the result. So, we will test this method. For this purpose, we will create another class including methods
that will test each one of the methods of the previous class (in this case, we have only one method to be tested). This is the most
JUnit Tutorial 3 / 26
common way of usage. Of course, if a method is very complex and extended, we can have more than one test methods for this
complex method. The details of creating test cases will be presented in the next sections. Below, there is the code of the class
named CalculateTest.java, which has the role of our test class:
CalculateTest.java
package com.javacodegeeks.junit;
import org.junit.Test;
@Test
public void testSum() {
System.out.println("@Test sum(): " + sum + " = " + testSum);
assertEquals(sum, testSum);
}
Let’s explain the above code. Firstly, we can see that there is a @Test annotation above the testSum() method. This
annotation indicates that the public void method to which it is attached can be run as a test case. Hence, the testSum()
method is the method that will test the sum() public method. We can also observe a method called assertEquals(sum,
testsum). The method assertEquals ([String message], object expected, object actual) takes
as inputs two objects and asserts that the two objects are equal.
If we run the test class, by right-clicking in the test class and select Run As → Junit Test, the program output will look like that:
Adding values: 2 + 5
@Test sum(): 7 = 7
To see the actual result of a JUnit test, Eclipse IDE provides a JUnit window which shows the results of the tests. In this case
where the test succeeds, the JUnit window does not show any errors or failures, as we can see in the image below:
JUnit Tutorial 4 / 26
so that the integers to be tested are not equal, the output will be:
Adding values: 2 + 5
@Test sum(): 7 = 10
And in the JUnit window, an error will appear and this message will be displayed:
java.lang.AssertionError: expected: but was:
at com.javacodegeeks.junit.CalculateTest.testSum(CalculateTest.java:16)
JUnit Tutorial 5 / 26
In this section we will mention the basic annotations supported in Junit 4. The table below presents a summary of those annota-
tions:
Annotation Description
@Test public void method() The Test annotation indicates that the public void method
to which it is attached can be run as a test case.
@Before public void method() The Before annotation indicates that this method must be
executed before each test in the class, so as to execute some
preconditions necessary for the test.
@BeforeClass public static void The BeforeClass annotation indicates that the static
method() method to which is attached must be executed once and
before all tests in the class. That happens when the test
methods share computationally expensive setup (e.g.
connect to database).
@After public void method() The After annotation indicates that this method gets
executed after execution of each test (e.g. reset some
variables after execution of every test, delete temporary
variables etc)
@AfterClass public static void method() The AfterClass annotation can be used when a method
needs to be executed after executing all the tests in a JUnit
Test Case class so as to clean-up the expensive set-up (e.g
disconnect from a database). Attention: The method
attached with this annotation (similar to BeforeClass)
must be defined as static.
@Ignore public static void method() The Ignore annotation can be used when you want
temporarily disable the execution of a specific test. Every
method that is annotated with @Ignore won’t be
executed.
Let’s see an example of a test class with some of the annotations mentioned above.
AnnotationsTest.java
package com.javacodegeeks.junit;
@BeforeClass
public static void onceExecutedBeforeAll() {
System.out.println("@BeforeClass: onceExecutedBeforeAll");
}
@Before
public void executedBeforeEach() {
testList = new ArrayList();
System.out.println("@Before: executedBeforeEach");
}
@AfterClass
public static void onceExecutedAfterAll() {
System.out.println("@AfterClass: onceExecutedAfterAll");
JUnit Tutorial 6 / 26
@After
public void executedAfterEach() {
testList.clear();
System.out.println("@After: executedAfterEach");
}
@Test
public void EmptyCollection() {
assertTrue(testList.isEmpty());
System.out.println("@Test: EmptyArrayList");
@Test
public void OneItemCollection() {
testList.add("oneItem");
assertEquals(1, testList.size());
System.out.println("@Test: OneItemArrayList");
}
@Ignore
public void executionIgnored() {
If we run the above test, the console output would be the following:
@BeforeClass: onceExecutedBeforeAll
@Before: executedBeforeEach
@Test: EmptyArrayList
@After: executedAfterEach
@Before: executedBeforeEach
@Test: OneItemArrayList
@After: executedAfterEach
@AfterClass: onceExecutedAfterAll
In this section we will present a number of assertion methods. All those methods are provided by the Assert class which
extends the class java.lang.Object and they are useful for writing tests so as to detect failures. In the table below there
is a more detailed explanation of the most commonly used assertion methods.
Assertion Description
void assertEquals([String message], Asserts that two values are equal. Values might be type of
expected value, actual value) int, short, long, byte, char or java.lang.Object. The first
argument is an optional String message.
void assertTrue([String message], Asserts that a condition is true.
boolean condition)
void assertFalse([String Asserts that a condition is false.
message],boolean condition)
void assertNotNull([String message], Asserts that an object is not null.
java.lang.Object object)
void assertNull([String message], java. Asserts that an object is null.
lang.Object object)
JUnit Tutorial 7 / 26
void assertSame([String message], java. Asserts that the two objects refer to the same object.
lang.Object expected, java.lang.Object
actual)
void assertNotSame([String message], Asserts that the two objects do not refer to the same object.
java.lang.Object unexpected, java.lang.
Object actual)
void assertArrayEquals([String Asserts that the array expected and the resulted array are
message], expectedArray, resultArray) equal. The type of Array might be int, long, short, char,
byte or java.lang.Object.
@Test
public void test() {
String obj1 = "junit";
String obj2 = "junit";
String obj3 = "test";
String obj4 = "test";
String obj5 = null;
int var1 = 1;
int var2 = 2;
int[] arithmetic1 = { 1, 2, 3 };
int[] arithmetic2 = { 1, 2, 3 };
assertEquals(obj1, obj2);
assertSame(obj3, obj4);
assertNotSame(obj2, obj4);
assertNotNull(obj1);
assertNull(obj5);
assertTrue(var1 var2);
assertArrayEquals(arithmetic1, arithmetic2);
}
In the class above we can see how these assert methods work.
• The assertEquals() method will return normally if the two compared objects are equal, otherwise a failure will be
displayed in the JUnit window and the test will abort.
• The assertSame() and assertNotSame() methods tests if two object references point to exactly the same object.
• The assertNull() and assertNotNull() methods test whether a variable is null or not null.
• The assertTrue() and assertFalse() methods tests if a condition or a variable is true or false.
JUnit Tutorial 8 / 26
• The assertArrayEquals() will compare the two arrays and if they are equal, the method will proceed without errors.
Otherwise, a failure will be displayed in the JUnit window and the test will abort.
JUnit Tutorial 9 / 26
Chapter 3
In this section we will show a complete example of using JUnit. We will see in detail how to create and run tests and we will
show how to use specific annotations and assertions of JUnit.
Let’s create a java project named JUnitGuide. In the src folder, we right-click and select New → Package, so as to create a new
package named com.javacodegeeks.junit where we will locate the class to be tested. For the test classes, it is considered
as good practice to create a new source folder dedicated to tests, so that the classes to be tested and the test classes will be in
different source folders. For this purpose, right-click your project, select New → Source Folder, name the new source folder test
and click Finish.
JUnit Tutorial 10 / 26
Tip: Alternatively, you can create a new source folder by right-clicking your project and select Properties → Java Build Path,
select the tab Source, select Add Folder → Create New Folder, write the name test and press Finish.
You can easily see that there are two source folders in your project:
JUnit Tutorial 11 / 26
You can also create a new package in the newly created test folder, which will be called com.javacodegeeks.junit, so
that your test classes won’t be located to the default package and we are ready to start!
Right-click the src folder and create a new java class called FirstDayAtSchool.java. This will be the class whose public
methods will be tested.
FirstDayAtSchool.java
package com.javacodegeeks.junit;
import java.util.Arrays;
return schoolbag;
}
To create a JUnit test case for the existing class FirstDayAtSchool.java, right-click on it in the Package Explorer view
and select New -→ JUnit Test Case. Change the source folder so that the class will be located to test source folder and ensure
that the flag New JUnit4 test is selected.
JUnit Tutorial 13 / 26
Then, click Finish. If your project does not contain the JUnit library in its classpath, the following message will be displayed so
as to add the JUnit library to the classpath:
JUnit Tutorial 14 / 26
Below, there is the code of the class named FirstDayAtSchoolTest.java, which is our test class:
FirstDayAtSchool.java
JUnit Tutorial 15 / 26
package com.javacodegeeks.junit;
import org.junit.Test;
@Test
public void testPrepareMyBag() {
System.out.println("Inside testPrepareMyBag()");
assertArrayEquals(bag1, school.prepareMyBag());
}
@Test
public void testAddPencils() {
System.out.println("Inside testAddPencils()");
assertArrayEquals(bag2, school.addPencils());
}
Now we can run the test case by right-clicking on the test class and select Run As → JUnit Test.
The program output will look like that:
Inside testPrepareMyBag()
My school bag contains: [Books, Notebooks, Pens]
Inside testAddPencils()
Now my school bag contains: [Books, Notebooks, Pens, Pencils]
and in the JUnit view will be no failures or erros. If we change one of the arrays, so that it contains more than the expected
elements:
String[] bag2 = { "Books", "Notebooks", "Pens", "Pencils", "Rulers"};
and we run again the test class, the JUnit view will contain a failure:
JUnit Tutorial 16 / 26
Else, if we change again one of the arrays, so that it contains a different element than the expected:
String[] bag1 = { "Books", "Notebooks", "Rulers" };
and we run again the test class, the JUnit view will contain once again a failure:
JUnit Tutorial 17 / 26
Let’s see in the above example how can we use the @Ignore annotation. In the test class FirstDayAtSchoolTest we
will add the @Ignore annotation to the testAddPencils() method. In that way, we expect that this testing method will be
ignored and won’t be executed.
package com.javacodegeeks.junit;
import org.junit.Ignore;
import org.junit.Test;
@Test
public void testPrepareMyBag() {
System.out.println("Inside testPrepareMyBag()");
assertArrayEquals(bag1, school.prepareMyBag());
}
@Ignore
@Test
public void testAddPencils() {
System.out.println("Inside testAddPencils()");
assertArrayEquals(bag2, school.addPencils());
}
Now, we will remove the @Ignore annotation from the testAddPencils() method and we will annotate the whole class
instead.
package com.javacodegeeks.junit;
import org.junit.Ignore;
import org.junit.Test;
@Ignore
public class FirstDayAtSchoolTest {
@Test
public void testPrepareMyBag() {
System.out.println("Inside testPrepareMyBag()");
assertArrayEquals(bag1, school.prepareMyBag());
}
@Test
public void testAddPencils() {
System.out.println("Inside testAddPencils()");
assertArrayEquals(bag2, school.addPencils());
}
The whose test class won’t be executed, so no result will be displayed int the console output and in the junit view:
JUnit Tutorial 19 / 26
In this section, we will see how to create suite tests. A test suite is a collection of some test cases from different classes that can
be run all together using @RunWith and @Suite annotations. This is very helpful if you have many test classes and you want
to run them all together instead of running each test one at a time.
When a class is annotated with @RunWith, JUnit will invoke the class in which is annotated so as to run the tests, instead of
using the runner built into JUnit.
Based on the classes of the previous sections, we can create two test classes. The one class will test the public method prepar
eMyBag() and the other test class will test the method addPencils(). Hence, we will eventually have the classes below:
PrepareMyBagTest.java
package com.javacodegeeks.junit;
import org.junit.Test;
import static org.junit.Assert.*;
@Test
public void testPrepareMyBag() {
System.out.println("Inside testPrepareMyBag()");
assertArrayEquals(bag, school.prepareMyBag());
AddPencilsTest.java
JUnit Tutorial 20 / 26
package com.javacodegeeks.junit;
import org.junit.Test;
import static org.junit.Assert.*;
@Test
public void testAddPencils() {
System.out.println("Inside testAddPencils()");
assertArrayEquals(bag, school.addPencils());
Now we will create a test suite so as to run the above classes together. Right-click the test source folder and create a new java
class named SuiteTest.java with the following code:
SuiteTest.java
package com.javacodegeeks.junit;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({ PrepareMyBagTest.class, AddPencilsTest.class })
public class SuitTest {
With the @Suite.SuiteClasses annotation you can define which test classes will be included in the execution.
So, if you right-click the test suite and select Run As → JUnit Test, the execution of both test classes will take place with the
order that has been defined in the @Suite.SuiteClasses annotation.
In this section we will see how to create parameterized tests. For this purpose, we will use the class mentioned in section 2.1
which provides a public method for adding integers. So, this will be the class to be tested.
But when a test class can be considered as a parameterized test class? Of course, when it fullfills all the following requirements:
• The class is annotated with @RunWith(Parameterized.class). As explained in the previous section, @RunWith
annotation enables JUnit to invoke the class in which is annotated to run the tests, instead of using the runner built into JUnit.
Parameterized is a runner inside JUnit that will run the same test case with different set of inputs.
• The class has a single constructor that stores the test data.
• The class has a static method that generates and returns test data and is annotated with the @Parameters annotation.
• The class has a test, which obviously means that it needs a method annotated with the @Test annotation.
JUnit Tutorial 21 / 26
Now, we will create a new test class named CalculateTest.java, which will follow the guidelines mentioned above. The
source code of this class follows.
CalculateTest.java
package com.javacodegeeks.junit;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class CalculateTest {
@Parameters
public static Collection addedNumbers() {
return Arrays.asList(new Integer[][] { { 3, 1, 2 }, { 5, 2, 3 },
{ 7, 3, 4 }, { 9, 4, 5 }, });
}
@Test
public void sum() {
Calculate add = new Calculate();
System.out.println("Addition with parameters : " + first + " and "
+ second);
assertEquals(expected, add.sum(first, second));
}
}
As we can observe in the class above, it fullfills all the above requirements. The method addedNumbers annotated with @
Parameters returns a Collection of Arrays. Each array includes the inputs/output numbers of each test execution. The number
of elements in each array must be the same with the number of parameters in the constructor. So, in this specific case, each array
includes three elements, two elements that represent the numbers to be added and one element for the result.
If we run the CalculateTest test case, the console output will be the following:
Addition with parameters : 1 and 2
Adding values: 1 + 2
Addition with parameters : 2 and 3
Adding values: 2 + 3
Addition with parameters : 3 and 4
Adding values: 3 + 4
Addition with parameters : 4 and 5
Adding values: 4 + 5
As we see in the output, the test case is executed four times, which is the number of inputs in the method annotated with @
Parameters annotation.
JUnit Tutorial 22 / 26
3.7 Rules
In this section we present a new feature of JUnit called Rules which allows very flexible addition or redefinition of the behavior
of each test method in a test class. For this purpose, @Rule annotation should be used so as to mark public fields of a test
class. Those fields should be of type MethodRule, which is an alteration in how a test method is run and reported. Multiple
MethodRules can be applied to a test method. MethodRule interface has a lot of implementations, such as ErrorCol
lector which allows execution of a test to continue after the first problem is found, ExpectedException which allows
in-test specification of expected exception types and messages, TestName which makes the current test name available inside
test methods, and many others. Except for those already defined rules, developers can create their own custom rules and use them
in their test cases as they wish.
Below we present the way we can use one of the existing rules named TestName in our own tests. TestName is invoked when
a test is about to start.
NameRuleTest.java
package com.javacodegeeks.junit;
import org.junit.*;
import org.junit.rules.TestName;
@Test
public void testA() {
System.out.println(name.getMethodName());
assertEquals("testA", name.getMethodName());
@Test
public void testB() {
System.out.println(name.getMethodName());
assertEquals("testB", name.getMethodName());
}
}
We can see that the @Rule annotation marks the public field name which is of type MethodRule and specifically, TestName
type. Then, we can use in our tests this name field and find for example the name of the test method, in this specific case.
3.8 Categories
Another new feature of JUnit is called Categories and allows you to group certain kinds of tests together and even include or
exclude groups (categories). For example, you can separate slow tests from fast tests. To assign a test case or a method to one
of those categories the @Category annotation is provided. Below there is an example of how we can use this nice feature of
JUnit, based on the release notes of JUnit 4.8.
public interface FastTests { /* category marker */
}
Firstly, we define two categories, FastTests and SlowTests. A category can be either a class or an interface.
JUnit Tutorial 23 / 26
public class A {
@Test
public void a() {
fail();
}
@Category(SlowTests.class)
@Test
public void b() {
}
}
In the above code, we mark the test method b() of class A with @Category annotation so as to indicate that this specific
method belongs to category SlowTests. So, we are able to mark not only whole classes but also some of their test methods
individually.
@Category({ SlowTests.class, FastTests.class })
public class B {
@Test
public void c() {
}
}
In the above sample of code, we can see that the whole class B is annotated with @Category annotation . Annotating a test
class with @Category annotation automatically includes all its test methods in this category. We can also see that a test class
or a test method can belong to more than one categories.
@RunWith(Categories.class)
@IncludeCategory(SlowTests.class)
@SuiteClasses({ A.class, B.class })
// Note that Categories is a kind of Suite
public class SlowTestSuite {
// Will run A.b and B.c, but not A.a
}
In this sample of code, we notice that there is a suite test named SlowTestSuite. Basically, categories are a kind of suite.
In this suite, we observe a new annotation called @IncludeCategory, indicating which categories will be included in the
execution. In this specific case, methods belonging to SlowTests category will be executed. Hence, only the test method b() of
class A will be executed as well as the test method c() of class B, which both belong to SlowTests category.
@RunWith(Categories.class)
@IncludeCategory(SlowTests.class)
@ExcludeCategory(FastTests.class)
@SuiteClasses({ A.class, B.class })
// Note that Categories is a kind of Suite
public class SlowTestSuite {
// Will run A.b, but not A.a or B.c
}
Finally, we change a little bit the test suite and we add one more new annotation called @ExcludeCategory, indicating which
categories will be excluded from the execution. In this specific case, only the test method b() of class A will be executed, as this
is the only test method that belongs explicitly to SlowTests category.
We notice that in both cases, the test method a() of class A won’t be executed as it doesn’t belong to any category.
JUnit Tutorial 24 / 26
Chapter 4
You can run your JUnit test outside Eclipse, by using the org.junit.runner.JUnitCore class. This class provides the
runClasses() method which allows you to execute one or several test classes. The return type of runClasses() method
is an object of the type org.junit.runner.Result. This object can be used to collect information about the tests. Also, in
case there is a failed test, you can use the object org.junit.runner.notification.Failure which holds description
of the failed tests.
The procedure below shows how to run your test outside Eclipse.
Create a new Java class named JunitRunner.java with the following code:
JunitRunner.java
package com.javacodegeeks.junit;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
• Open command prompt and move down directories so as to find the directory where the two classes are located.
• Compile the Test class and the Runner class.
C:Userskonstantinaeclipse_luna_workspaceJUnitGuidetestcomjavacodegeeksjunit>javac - ←-
classpath "C:UserskonstantinaDownloadsjunit-4.11.jar";"C: ←-
UserskonstantinaDownloadshamcrest-core-1.3.jar"; AssertionsTest.java JunitRunner.java
As we did in Eclipse, we should also include library jars of JUnit to our classpath. * Now run the JunitRunner.
JUnit Tutorial 25 / 26
C:Userskonstantinaeclipse_luna_workspaceJUnitGuidetestcomjavacodegeeksjunit>java -classpath ←-
"C:UserskonstantinaDownloadsjunit-4.11.jar";"C:UserskonstantinaDownloadshamcrest-core ←-
-1.3.jar"; JunitRunner
Chapter 5
Conclusions
This was a detailed guide about JUnit testing framework, the most popular testing framework in Java.
If you enjoyed this, then subscribe to our newsletter to enjoy weekly updates and complimentary whitepapers! Also, check out
JCG Academy for more advanced training!
Download: You can download the full source code of this guide here : JUnitGuide.zip