JUnit 4
The ultimate unit test framework
copyright 2008 trainologic LTD
JUnit 4
• Introduction
• Test Cases and Test Suites
• Parameterized Tests
• Running JUnit Tests
copyright 2008 trainologic LTD
JUnit 4
Introduction to JUnit
• If we had to test our code by hand, it would be
practically impossible to handle Test Driven
Development.
• JUnit is the most popular automated testing framework.
3
copyright 2008 trainologic LTD
JUnit 4
Introduction to JUnit
• A simple yet powerful open-source framework to write
Java automated tests.
• It is an instance of the xUnit architecture.
• Licensed by IBM's Common Public License Version 0.5
• Hosted by Sourceforge
• Current version 4.4
4
copyright 2008 trainologic LTD
JUnit 4
Introduction to JUnit
• JUnit consists of the following components:
• Runners - Run the tests.
• Fixtures - Initialize common objects.
• Assertions - Test expected results.
5
copyright 2008 trainologic LTD
JUnit 4
Introduction to JUnit
• When we use JUnit we write:
• Tests = Methods.
• Test Case = Class with several tests.
• Test Suite = An aggregation of several test cases
(optional).
6
copyright 2008 trainologic LTD
JUnit 4
Installing JUnit
• Download junit.zip.
• Unzip it.
• Add the junit.jar to you classpath.
• And.. Voila... you are good to go.
Usually this is not necessary as most modern IDEs
come with built-in JUnit support.
7
copyright 2008 trainologic LTD
JUnit 4
• Introduction
• Test Cases and Test Suites
• Parameterized Tests
• Running JUnit Tests
copyright 2008 trainologic LTD
JUnit 4
Test
• A simple void method checking a piece of code.
• Tests are marked with the @Test annotation.
@Test
public void testAdd() throws Exception {
double first = 5;
double second = 5;
Calculator calc = new Calculator();
Assert.assertEquals(first + second, calc.add(first, second));
}
9
copyright 2008 trainologic LTD
JUnit 4
Test
• Test methods optionally are declared as throwing
Exception.
• In case an Exception is thrown by the test, the test is
marked as “failed”.
• Throwing an Exception is optional and is not the
common way to fail a test. Usually, what fails a test is a
failed assertion.
10
copyright 2008 trainologic LTD
JUnit 4
Test
• In case throwing an Exception is the expected behavior,
we can mark the to expect a specific type of Exception.
• This test will fail in case it doesn’t throw
LoginException.
@Test(expected=LoginException.class)
public void testLoginException() throws LoginException {
...
}
11
copyright 2008 trainologic LTD
JUnit 4
Test
• The class org.junit.Assert is a collection of static assert
methods.
• These methods help us check the output of the checked
code against the expected value.
• In case the asserted condition is false, the test fails,
and the supplied message is logged.
Assert.assertEquals(message, expected, returnValue);
12
copyright 2008 trainologic LTD
JUnit 4
Test
• There is a wide variety of assertions:
13
copyright 2008 trainologic LTD
JUnit 4
Test
• Another way to fail the test is by calling the method
fail().
@Test
public void testSomething() throws Exception {
...
switch(i) {
case a:
... break;
case b:
... break;
default:
Assert.fail();
}
}
14
copyright 2008 trainologic LTD
JUnit 4
Test
• It is also possible to add a timeout to the test.
• In case the test hasn’t finished befoer timeout, it will
fail.
• Set the timeout attribute of the @Test annotation to
the allowed time in milliseconds.
@Test(timeout=1)
public void testSomething() throws Exception {
...
}
15
copyright 2008 trainologic LTD
JUnit 4
Test Cases
• A Test Case is a simple class which includes one or
more test methods:
public class ExampleTestCase {
@Test
public void testAdd() throws Exception {...}
@Test
public void testSubstruct() throws Exception {...}
16
copyright 2008 trainologic LTD
JUnit 4
Test Cases
• Sometimes, tests share resources.
Will the following example work?
public class ExampleTestCase {
private ShoppingCart cart;
@Test
public void testAddToCart() throws Exception {
cart.add(...);
...
}
@Test
public void testCheckout() throws Exception {
cart.checkout();
...
}
}
17
copyright 2008 trainologic LTD
JUnit 4
Test Cases
• Even though ShoppingCart is a shared resource, we
wouldn’t want both tests to use the same cart.
• This will create coupling between the tests.
• To decouple the tests and avoid code duplication, we
use Fixtures.
18
copyright 2008 trainologic LTD
JUnit 4
Fixtures
• Fixtures are simple methods annotated with @Before
and @After.
• Using fixtures allows us to initialize objects before each
test and clean up after each test.
public class ExampleTestCase {
private ShoppingCart cart;
@Before
public void init() {cart = new ShoppingCart();}
@After
public void destroy() {cart.rollback();}
@Test
public void testAddToCart() throws Exception {...}
@Test
public void testCheckout() throws Exception {...}
19
copyright 2008 trainologic LTD
JUnit 4
Fixtures
init() - @Before
20
copyright 2008 trainologic LTD
JUnit 4
Fixtures
init() - @Before testAddToCart()
20
copyright 2008 trainologic LTD
JUnit 4
Fixtures
init() - @Before testAddToCart() destroy() - @After
20
copyright 2008 trainologic LTD
JUnit 4
Fixtures
init() - @Before testAddToCart() destroy() - @After
init() - @Before
20
copyright 2008 trainologic LTD
JUnit 4
Fixtures
init() - @Before testAddToCart() destroy() - @After
init() - @Before testCheckout()
20
copyright 2008 trainologic LTD
JUnit 4
Fixtures
init() - @Before testAddToCart() destroy() - @After
init() - @Before testCheckout() destroy() - @After
20
copyright 2008 trainologic LTD
JUnit 4
Fixtures
init() - @Before testAddToCart() destroy() - @After
init() - @Before testCheckout() destroy() - @After
This way, we avoid coupling and code duplication.
20
copyright 2008 trainologic LTD
JUnit 4
Shared Fixtures
• Shared Fixtures run once for all the Test Case, thus
allowing us to really share the object between tests.
• Shared Fixtures are simple methods annotated with
@BeforeClass and @AfterClass.
If you need a Shared Fixture to test your code, this is
usually a sign of an unwanted dependency in your
code. We will discuss this in detail in the next chapters.
21
copyright 2008 trainologic LTD
JUnit 4
Protected Methods
• Testing public methods is simple, but how can we test
protected methods?
• Easy... just put the test code in the same package (not
necessarily in the same source folder).
22
copyright 2008 trainologic LTD
JUnit 4
Private Methods
• OK... but what about private methods.
• Well, if you need to unit test a private method, it is
usually a sign the method should be promoted to
another class for reuse.
• In case you insist, you can use PrivilegedAccessor (an
open-source project).
23
copyright 2008 trainologic LTD
JUnit 4
Test Suites
• Test Suites are a bundle of Test Cases wrapped
together.
• A Test Suite implements the composite pattern in order
to enable one Suite to contain another.
24
copyright 2008 trainologic LTD
JUnit 4
Test Suites
@RunWith(Suite.class)
@SuiteClasses(value={FirstTest.class, SecondItemTest.class})
public class AllTests {}
25
copyright 2008 trainologic LTD
JUnit 4
• Introduction
• Test Cases and Test Suites
• Parameterized Tests
• Running JUnit Tests
copyright 2008 trainologic LTD
JUnit 4
Parameterized Tests
• Sometimes, we want to run the same test code with
different parameters, several times.
• For example, we want to test the add() method with
different arguments sets.
• One way of doing it would be to duplicate the code in
the same test method.
• Another way would be to duplicate the whole test
method.
• The problem is... We do not appreciate code
duplication.
27
copyright 2008 trainologic LTD
JUnit 4
Parameterized Tests
• An elegant way to avoid this code duplication is
Parameterized Tests.
• Parameterized Test is a simple test method that is
executed several times with different values assigned
to class members.
• To write it use the @RunWith and @Parameters
annotations.
28
copyright 2008 trainologic LTD
JUnit 4
Parameterized Tests
@RunWith(Parameterized.class)
public class ParameterizedExample {
double first, second; Calculator calc;
public ParameterizedExample(double first, double second) {
this.first = first; this.second = second;
}
@Parameters
public static Collection parameterValues() {
return Arrays.asList(new Object[][]{{5d,5d}, {5d,10d}});
}
@Before
public void init() {calc = new Calculator();}
public void testAdd() {
Assert.assertEquals(first + second, calc.add(first, second));
}
}
29
copyright 2008 trainologic LTD
JUnit 4
Parameterized Tests
• The testAdd() method is executed twice.
• Once whith first=5d and second=5d.
• And next with first=5d and second=10d.
• In the result report, two distinct tests will be shown.
30
copyright 2008 trainologic LTD
JUnit 4
• Introduction
• Test Cases and Test Suites
• Parameterized Tests
• Running JUnit Tests
copyright 2008 trainologic LTD
JUnit 4
Running Tests
• To run a test we have to use one of the runners.
• The runners are java classes that run tests.
• There are three common ways to use runners:
• Command-Line.
• Through IDE Support.
• Using Apache Ant.
32
copyright 2008 trainologic LTD
JUnit 4
Command-Line
• Use Java to execute org.junit.runner.JUnitCore and
pass it the test class name as an argument.
java org.junit.runner.JUnitCore <test class name>
33
copyright 2008 trainologic LTD
JUnit 4
Using IDE
• A more convenient and popular way is to use the built-
in JUnit support of our IDE.
• We have chosen Eclipse for the purpose of this course,
but all popular Java IDEs has JUnit support.
34
copyright 2008 trainologic LTD
JUnit 4
Using IDE - Eclipse
• Eclipse supports JUnit in the Test development level
and in the executing and reporting levels.
• In the development level, Eclipse supplies wizards for
creating new TestCases and TestSuites.
• The more interesting part is the Eclupse’s support in
the execution level.
35
copyright 2008 trainologic LTD
JUnit 4
Using IDE - Eclipse
• Right-click any TestCase or TestSuit class, and select
run as->JUnit Test.
• Choosing this option immediately executes the selected
test and opens a report.
36
copyright 2008 trainologic LTD
JUnit 4
Using IDE - Eclipse
• Using the Run Dialog, we can also make a run
configuration that will run all Tests in a specific project
or package.
37
copyright 2008 trainologic LTD
JUnit 4
Using Apache Ant
• Since version 1.7, Ant comes with <junit> task as a
part of its optional tasks.
• This task enables executing JUnit tests from Ant and
generate reports.
<junit>
<test name="my.test.TestCase"/>
</junit>
38
copyright 2008 trainologic LTD
JUnit 4
Using Apache Ant
• Ant supports many sophisticated test execution modes.
• See <junit> task documentation for more details.
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement location="${build.tests}"/>
<pathelement path="${java.class.path}"/>
</classpath>
<formatter type="plain"/>
<batchtest fork="yes" todir="${reports.tests}">
<fileset dir="${src.tests}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
39
copyright 2008 trainologic LTD
JUnit 4
Summary
• JUnit is a simple yet powerful testing framework.
• It supports the notion of TestCases and TestSuits.
• Using JUnit makes it easy to write test methods that
run in an isolated environment.
• Using different runners we can constantly run our tests
and get immediate feedback about our code
correctness.
40
copyright 2008 trainologic LTD