JUnit tests
Object Oriented Programming
http://softeng.polito.it/courses/09CBI
Version 3.1.0 - April 2018
© Marco Torchiano, 2018
This work is licensed under the Creative Commons Attribution-
NonCommercial-NoDerivatives 4.0 International License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-nd/4.0/.
You are free: to copy, distribute, display, and perform the work
Under the following conditions:
Licensing Note
§ Attribution. You must attribute the work in the manner specified by
the author or licensor.
§ Non-commercial. You may not use this work for commercial purposes.
§ No Derivative Works. You may not alter, transform, or build upon this
work.
§ For any reuse or distribution, you must make clear to others the
license terms of this work.
§ Any of these conditions can be waived if you get permission from the
copyright holder.
Your fair use and other rights are in no way affected by the above.
2
JUnit
§ JUnit is a testing framework for Java
programs
w Written by Kent Beck and Erich Gamma
§ It is a framework with unit-testing
functionalities
§ Integrated in Eclipse development
Environment
http://www.junit.org
Unit Testing
§ Unit testing is particularly important
when software requirements change
frequently
w Code often has to be refactored to
incorporate the changes
w Unit testing helps ensure that the
refactored code continues to work
JUnit Framework
§ JUnit helps the programmer:
w Define and execute tests and test suites
w Formalize requirements and clarify
architecture
w Write and debug code
w Integrate code and always be ready to
release a working version
History
§ 1997 on the plane to OOPSLA97 Kent
Beck and Erich Gamma wrote JUnit
§ Junit.org – August 2000
§ Junit 3.8.1 – September 2002
§ Junit 4.0 – February 2006
w Latest release: 4.12 - Dec 2012
§ Junit 5.0 – September 2017
6
What JUnit does
§ For each test (method) JUnit
w calls pre-test fixture
– Intended to acquire resources and create any
objects that may be needed for testing
w calls the test method
w calls post-test fixtures
– Intended to release resources and remove any
objects you created
Test method
§ A test method doesn’t return a result
§ The test method performs operations
and checks the results
§ Checks are performed using a set of
assert*() method
§ The JUnit framework detects the
anomalies and deals with them
assert*() methods
assertTrue(boolean test)
assertFalse(boolean test)
assertEquals(expected, actual)
assertSame(Object expected,
Object actual)
assertNotSame(Object expected,
Object actual)
assertNull(Object object)
assert*() methods
§ For a condition
assertTrue(condition)
w If the tested condition is
– true => proceed with execution
– false => abort the test method execution,
prints out the optional message
assert*() methods
assertNotNull(Object object)
fail()
w All the above may take an optional String
message as the first argument, e.g.
static void assertTrue(
String message,
boolean test)
assert*()
§ For objects, int, long, byte:
assertEquals( expected, actual)
w Ex. assertEquals( 2 , unoStack.size() );
§ For floating point values:
assertEquals(expected,actual,err)
w Ex. assertEquals(1.0, Math.cos(3.14),
0.01);
JUnit 3
SYNTAX
13
Test a Stack extends TestCase
public class StackTest extends TestCase {
public void testStack() { Test method name:
Stack aStack = new Stack(); testSomething
assertTrue("Stack should be empty!",
aStack.isEmpty());
aStack.push(10);
assertTrue("Stack should not be empty!",
!aStack.isEmpty());
aStack.push(-4);
assertEquals(-4, aStack.pop());
assertEquals(10, aStack.pop());
}
}
One or more assertions
to check results
Test a Stack
public void testStackEmpty() {
Stack aStack = new Stack();
assertTrue(“Stack should be empty!”,
aStack.isEmpty());
aStack.push(10);
assertFalse(“Stack should not be empty!”,
aStack.isEmpty());
}
public void testStackOperations() {
Stack aStack = new Stack();
aStack.push(10);
aStack.push(-4);
assertEquals(-4, aStack.pop());
assertEquals(10, aStack.pop());
}
Running a test case
§ Running a test case
w Executes all methods
– public
– Returning void
– With no arguments
– Name starting with “test”
w Ignores the rest
§ The class can contain helper methods
w That are not public
w Or not starting with “test”
Creating a test class
§ Define a subclass of TestCase
§ Override the setUp() method to
initialize object(s) under test.
§ Override the tearDown() method to
release object(s) under test.
§ Define one or more public testXXX()
methods that exercise the object(s)
under test and assert expected results.
Implementing setUp() method
§ Override setUp() to initialize the
variables, and objects
w Implements a fixture
§ Since setUp() is your code, you can
modify it any way you like (such as
creating new objects in it)
§ Reduces the duplication of code
The tearDown() method
§ In most cases, the tearDown()
method doesn t need to do anything
w The next time you run setUp(), your
objects will be replaced, and the old
objects will be available for garbage
collection
w Like the finally clause in a try-catch-
finally statement, tearDown() is where
you would release system resources
(such as streams)
Test suites
§ Allow running a group of related tests
§ To do so, group your test methods in
a class which extends TestSuite
TestSuite
§ Combine many test cases in a test suite:
public class AllTests extends TestSuite {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(StackTester.class);
suite.addTestSuite(AnotherTester.class);
}
Example: Counter class
§ For the sake of example, we will
create and test a trivial counter
class
w The constructor will create a counter and
set it to zero
w The increment method will add one to
the counter and return the new value
w The decrement method will subtract one
from the counter and return the new
value
Example: Counter class
§ We write the test methods before we
write the code
w This has the advantages described earlier
w Depending on the JUnit tool we use, we
may have to create the class first, and we
may have to populate it with stubs
(methods with empty bodies)
§ Don t be alarmed if, in this simple
example, the JUnit tests are more
code than the class itself
JUnit tests for Counter
public class CounterTest extends TestCase {
Counter counter1;
public void setUp() {
// creates a (simple) test fixture
counter1 = new Counter();
}
protected void tearDown() { }
// no resources to release
JUnit tests for Counter…
public void testIncrement() {
assertTrue(counter1.increment()== 1);
assertTrue(counter1.increment()== 2);
}
public void testDecrement() {
assertTrue(counter1.decrement()==-1);
}
} // End from last slide
The Counter class itself
public class Counter {
int count = 0;
public int increment() {
return ++count;
}
public int decrement() {
return --count;
}
public int getCount() {
return count;
} }
Junit 4
SYNTAX
27
JUnit 4
§ Make use of java annotations
w Less constraints on names
w Easier to read/write
§ Backward compatible with JUnit 3
§ Assertions
w assert*() methods
w assertThat() method
– To use the Hamcrest matchers
28
Test a Stack (JUnit4) Any class
public class TestStack {
@Test @Test annotation
public void testStack() {
Stack aStack = new Stack();
assertTrue("Stack should be empty",
aStack.isEmpty());
aStack.push(10);
assertFalse("Stack should not be empty!",
aStack.isEmpty());
aStack.push(-4);
assertEquals(-4, aStack.pop());
assertEquals(10, aStack.pop());
}
} One or more assertions
to check results
Running a test case
§ The JUnit runner
w Executes all methods
– Annotated with “@Test”
– public
– Returning void
– With no arguments
w Ignores the rest
§ The class can contain helper methods provided
they are not annotated
w Not public
The pre-test fixture
§ Annotate a method with @Before to
make it a pre-test fixture:
w It is executed before each test method is run
w It is the place to initialize attributes that will
be used by tests
§ There no limit to the setup you can do in
a pre-test method: it is a general method
§ It helps reducing duplication of code
The post-test fixture
§ Annotate a method with @After to make
it a post-test fixture
w It is executed after each test method is run
w It is where you would release system
resources (such as streams)
§ In most cases, a post-test fixture is not
required
w Before the next test is executed the setup
fixture is run so attribute will be re-
initialized
TestSuite
§ Combines many test cases in a test
suite:
@RunWith(Suite.class)
@SuiteClasses({
TestStack.class, AnotherTest.class
})
public class AllTests { }
JUnit 4 Annotations
§ @Test
w Marks test methods
§ @Before and @After
w Mark pre and post fixtures
§ Test suites require:
§ @RunWith(Suite.class)
§ @Suite.SuiteClasses({ … })
34
JUnit 4 Packages and classes
§ All classes are in packages org.junit
§ Assertions are made available with
w import static org.junit.Assert.*;
§ Annotations have to be imported as
w import org.junit.After;
w import org.junit.Before;
w import org.junit.Test;
35
Counter test with Junit 4
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class CounterTests {
private Counter counter;
@Before
public void setUp() throws Exception {
counter = new Counter(); }
@After
public void tearDown() throws Exception {}
36
Counter test with Junit 4
@Test
public void testGetCounterInitial() {
assertEquals(0,counter.getCount()); }
@Test
public void testIncrement() {
assertEquals(1,counter.increment());
assertEquals(2,counter.increment()); }
@Test
public void testDecrement() {
assertEquals(-1,counter.decrement()); }
}
37
Junit 4 test suite
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({ CounterTests.class })
public class AllTests { }
38
ECLIPSE JUNIT PLUG-IN
Junit in Eclipse - Run as JUnit Test
§ Run
§ Run As..
§ Junit Test
Red / Green Bar
expected <-3> but was <-4>
…use JUnit
Keep the bar green to keep the code clean…
Organizing Tests in Eclipse
§ Second source folder
w Place tests within a second source folder
w Allows clear separation
w Add JUnit library to the project
§ Separate project
w Place tests inside a separate project
w No unit test libraries are added to your
primary project
w Refer to the primary project
JUnit in Eclipse Path Setup
§ When creating a new test case
w Eclipse suggests adding the JUnit library
§ When importing a test, the library
must be added explicitly
w open project s property window
w java build path
w libraries
w JUnit
USING JUNIT
45
Test-Driven Development
§ Specify a portion of the feature yet to be
coded
§ Run the test and see it fail (red bar)
§ Write code until the tests pass (green
bar)
§ Repeat until whole feature implemented
§ Refactor
w Keeping the bar green
Bug reproduction
§ When a bug is reported
§ Specify the expected correct outcome
§ See the test fail
w Reproduce the bug
§ Modify the code until the bug-fix tests
pass.
§ Check for regressions
47
Guidelines
§ Test should be written before code
§ Test everything that can break
§ Run tests as often as possible
§ Whenever you are tempted to type
something into a print statement or a
debugger expression write it as a test
– M.Fowler
48
Limitations of unit testing
§ JUnit is designed to call methods and
compare the results they return
against expected results
w This ignores:
– Programs that do work in response to
GUI commands
– Methods that are used primary to
produce output
Limitations of unit testing…
§ Heavy use of JUnit encourages a
functional style, where most
methods are called to compute a
value, rather than to have side effects
w This can actually be a good thing
w Methods that just return results, without
side effects (such as printing), are
simpler, more general, and easier to
reuse
Summary: elements of JUnit
§ assert*()
w Comparison functions
§ Test cases
w Are implemented by methods in test
classes
§ TestSuite
w Class containing a sequence of TestCase
Why JUnit
§ Allow you to write code faster while increasing
quality
§ Elegantly simple
§ Check their own results and provide immediate
feedback
§ Tests is inexpensive
§ Increase the stability of software
§ Developer tests
§ Written in Java
§ Free
§ Gives proper uniderstanding of unit testing
References
§ K.Beck, E.Gamma. Test Infected:
Programmers Love Writing Tests
w http://members.pingnet.ch/gamma/
junit.htm
§ Junit home page
w https://junit.org
§ Hamcrest matchers
w http://hamcrest.org/JavaHamcrest/
53