3 JUnit
3 JUnit
with JUnit
increment
+ system
Written before Prioritized functionalities Executed after the development
2
Testing tools
Jemmy/Abbot/JFCUnit/
GUI
Cactus
Business Logic
Persistence Layer
Junit/SQLUnit/XMLUnit
3
Junit is a unit test environment for Java programs developed by Erich Gamma and Kent Beck. Writing test cases Executing test cases Pass/fail? (expected result = obtained result?) Consists in a framework providing all the tools for testing. framework: set of classes and conventions to use them. It is integrated into eclipse through a graphical plugin.
4
Test framework
test
cases are Java code test case = sequence of operations +inputs + expected
values
doubleOf2();
//..
}
5
JUnit tests substitute the use of main() to check the program behaviour All we need to do is: junit.framework.* write a sub-class of TestCase add to it one or more test methods run the test using JUnit
Framework elements
TestCase Base class for classes that contain tests assert*() Method family to check conditions TestSuite Enables grouping several test cases
Testcase 1 Testsuite Testcase 2 Testcase 3
An example
class Stack { public boolean isEmpty(){ ... } public void push(int i){ ... } public int pop(){ ... } }
import junit.framework.TestCase; public class StackTester extends TestCase { public StackTester(String name) { super(name); } public void testStack() { Stack aStack = new Stack(); if(!aStack.isEmpty()) { System.out.println(Stack should be empty!); aStack.push(10); aStack.push(-4); System.out.println(Last element: + aStack.pop()); System.out.println(First element: +aStack.pop()); } }
Assert*()
They are public methods defined in the base class TestCase Their names begin with assert and are used in test methods
If the condition is false: test fails execution skips the rest of the test method the message (if any) is printed If the condition is true: execution continues normally
9
Assert*()
for a boolean condition assertTrue(message for fail, condition); assertFalse(message, condition); obtained for object, int, long, and byte values assertEquals(expected_value, expression); for float and double values assertEquals(expected, expression, error); for objects references assertNull(reference) assertNotNull(reference)
http://junit.org/apidocs/org/junit/Assert.html
10
Assert: example
public void testStack() { Stack aStack = new Stack(); 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()); } class Stack { public boolean isEmpty(){ ... } public void push(int i){ ... } public int pop(){ ... } }
11
Code Modularization
Working rule
For each test case class, JUnit execute all of its public test methods i.e. those whose name starts with test ignores everything else Test classes can contain helper methods provided that are: non public, or whose name does not begin with test
13
TestSuite
junit.framework.*
public static TestSuite suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(StackTester.class); suite.addTestSuite(AnotherTester.class); return suite; }
}
14
Test of Exceptions
There are two cases: 1. We expect a normal behavior and then no exceptions. 2. We expect an anomalous behavior and then an exception.
15
We expect an exception
try { // we call the method with wrong parameters
setUp() method initialize object(s) under test. called before every test method tearDown() method release object(s) under test called after every test case method.
ShoppingCart cart; Book book;
protected void setUp() { cart = new ShoppingCart(); book = new Book(JUnit", 29.95); cart.addItem(book); }
18
In Eclipse
Create
a new project Open projects property window (File -> Properties) Select: Java build path Select: libraries Add Library Select Junit
19
Set the parameters: Junit 3.x or 4.x name of the class etc. Finish
20
21
Pass
Most things are about equally easy JUnit 4 can still run JUnit 3 tests All the old assertXXX methods are the same JUnit 4 has some additional features JUnit 4 provides protection against infinite loops Junit 4 uses annotations (@)
23
JUnit 4 requires Java 5 or newer Dont extend junit.framework.TestCase; just use an ordinary class Import org.junit.* and org.junit.Assert.*
Use a static import for org.junit.Assert.* Static imports replace inheritance from junit.framework.TestCase Instead of a setUp method, put @Before before some method Instead of a tearDown method, put @After before some method Instead of beginning test method names with test, put @Test before each test method
24
Annotations in J2SE
J2SE 5 introduces the Metadata feature (data about data) Annotations allow you to add decorations to your code (remember javadoc tags: @author ) Annotations are used for code documentation, compiler processing (@Deprecated ), code generation, runtime processing New annotations can be created by developers
http://java.sun.com/docs/books/tutorial/java/javaOO/annotations.html
25
While it's not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with @Override fails in correctly overriding the original method in its superclass, the compiler generates an error.
26
Declare any variables you are going to use, e.g., an instance of the class being tested
MyProgram program; int [ ] array; int solution;
27
If needed, define one method to be executed just once, to do cleanup after all the tests have been completed
@AfterClass public static void tearDownClass() throws Exception { // one-time cleanup code }
28
If needed, define one or more methods to be executed after each test, e.g., typically for releasing resources (files, etc.)
@After public void tearDown() { }
29
More than one @Before and/or @After methods can be defined in a test case
We can inherit @Before and @After methods from a superclass; execution is as follows:
Execute the @Before methods in the superclass Execute the @Before methods in this class Execute a @Test method in this class Execute the @After methods in this class Execute the @After methods in the superclass
30
31
Some method calls should throw an exception. We can specify that an exception is expected. The test will pass if the expected exception is thrown, and fail otherwise
@Test (expected=IllegalArgumentException.class) public void factorial() { program.factorial(-5); }
32
Parameterized tests
Using @RunWith(value=Parameterized.class) and a method @Parameters, a test class is executed with several inputs
@RunWith(value=Parameterized.class) public class FactorialTest { private long expected; private int value;
@Parameters public static Collection data() { return Arrays.asList( new Object[ ][ ] { { 1, 0 }, { 1, 1 }, { 2, 2 }, { 120, 5 } }); } public FactorialTest(long expected, int value) { // constructor this.expected = expected; this.value = value; } @Test public void factorial() { assertEquals(expected, new Calculator().factorial(value)); } }
33
Test suites
34
Instead of JUnit 3s AssertionFailedError, now failed tests throw an AssertionError There is now an additional version of assertEquals for arrays of objects: assertEquals(Object[] expected, Object[] actual) JUnit 3 had an assertEquals(p, p) method for each kind of primitive p, but JUnit 4 only has an assertEquals(object, object) and depends on autoboxing
@Override public boolean equals(Object o){ return ; }
35
Autoboxing example
long sum(long x, long y) { return x + y; } @Test public void sum() { assertEquals(4, s.sum(2, 2)); }
assertEquals no longer exists for primitives, only for objects! Hence, the 4 is autoboxed to an Integer, while sum returns a long The error message means: expected int 4, but got long 4 To make this work, change the 4 to a 4L or (long)4
Note that this problem has been fixed starting form JUnit 4.4
36
Test case 1
37
38
39
40
Test last The conventional way for testing in which testing follows the implementation
Test first The Extreme-Programming view in which testing is used as a developement tool
41
Test last
New functionality
Understand
Implement functionality
Write tests Run all tests
fail
Rework
Result?
pass
Next functionality
42
Test first
New functionality
Understand Add a single test Add code for the test Run all test
fail
Rework
Result?
pass
No
Next functionality
Yes
Functionality complete?
43
Each method has associated a testcase the confidence of our code increases It simplifies: refactoring/restructuring maintenance the introduction of new functionalities Test first help to build the documentation testcases are good use samples Programming is more fun
44
Add a testcase
Run test
Rework
Junit in practice
Example: CurrentAccount cc = new CurrentAccount(); cc.deposit(12); cc.draw(-8); cc.deposit(10); cc.settlement() expected value
14 euro!
46
Add a testcase
47
test first
public void test_settlement() { CurrentAccount c = new CurrentAccount(); c.deposit(12); c.draw(-8); c.deposit(10); assertEquals(14, c.settlement()); } }
49
class CurrentAccount { int account[]; int lastMove; CurrentAccount(){ lastMove=0; account=new int[10]; }
Run test
51
Rework
53
class CurrentAccount { int account[]; int lastMove; CurrentAccount(){ lastMove=0; account=new int[10]; } public void deposit(int value){ } public void draw(int value) { } public int settlement() { int result = 0 for (int i=0; i<account.length; i++) { result = result + account[i]; } return result; } public static void main(String args[]) {} }
Rework
class Test_CurrentAccount extends TestCase{ public void test_settlementVoid() { currentAccount c = new currentAccount(); assertEquals(0, c.settlement()); } public void test_settlement() { currentAccount c = new currentAccount(); c.deposit(12); c.draw(-8); c.deposit(10); assertEquals(14, c.settlement()); } }
Run test
55
Add a testcase
57
class CurrentAccount { int account[]; int lastMove; CurrentAccount(){ lastMove=0; account=new int[10]; }
Run test
59
Rework
61
class CurrentAccount { int account[]; int lastMove; CurrentAccount(){ lastMove=0; account=new int[100]; }
Rework
class Test_currentAccount extends TestCase {
public void test_realCaseSettlement() { currentAccount c = new currentAccount(); for (int i=0; i <10 ; i++) c.deposit(1); c.draw(-10); assertTrue(0, c.settlement()); } }
Run test
63
65
Refactoring
Run test
67
The End
69
xUnit
Junit: it is one of many in the xUnit family. NUnit It is an open source unit testing framework for Microsoft .NET. It serves the same purpose as JUnit does in the Java world.
2.1 ActionScript 2.2 Ada 2.3 BPEL 2.4 C 2.5 C++ 2.6 ColdFusion (CFML) 2.7 Delphi 2.8 Emacs Lisp 2.9 Fortran 2.10 Haskell 2.11 Internet 2.12 Java 2.13 JavaScript 2.14 Lasso 2.15 MATLAB 2.16 MySQL 2.17 .NET programming languages 2.18 Objective-C 2.19 Ocaml 2.20 PegaRULES Process Commander
2.21 Perl 2.22 PHP 2.23 PL/SQL 2.24 PowerBuilder 2.25 Prolog 2.26 Python 2.27 REALbasic 2.28 Ruby 2.29 SAS 2.30 Scala 2.31 Shell 2.32 Simulink 2.33 Smalltalk 2.34 SQL 2.35 Tcl 2.36 Transact-SQL 2.37 Visual FoxPro 2.38 Visual Basic 2.39 XML 2.40 XSLT 2.41 Other
70
Coverage testing (JCoverage, Clover, ) Integration testing System/GUI testing (Jemmy, Abbot, ) Testing legacy applications Testing J2EE applications Testing database applications. Testing EJBs Testing Web applications (HttpUnit, JWebUnit, ) Testing Web services Testing in isolation with Mock Objects
71