JUnit
By: Anupam Nanda
Outline
Testing Overview
Why Unit Test?
JUnit
Testing State
JUnit With Eclipse
Problems
Test Testing
Supplement
Summary
Conclusion
Philosophy
“Any program feature
without an automated test
simply doesn’t exist.”
Analogy
“It's like trying to build a pyramid by starting at the
top, rather than the bottom. No matter how hard
you try, you're doomed to failure.”
Testing pyramid
Deli o rk
v r s w
app ered om e r re
licat
ion r y cust lo pe
An g ve
d e
er /
Itera to m
tion u s
build C
s e
r tim
e
API e lop
e v
D
Testing
“Exercising a product to identify differences
between expected and actual behaviour”
Testing is more natural than formal
methods.
Testing may scale better than formal
methods, but at the cost of “state space
coverage”
The challenge in testing is to efficiently
cover the state space.
Testing Contd…..
Testing helps increase our confidence in our code
Testing is a comparison:
Expected behavior of the component
See javadoc description
Actual behavior of the component
Run the code
Three parts:
Implementation, specification, test cases
Test-driven development
Write tests first!
Types of Testing
Unit
per module testing
ensures components interact appropriately
System
system works in realistic environment
User Acceptance
system supports the business for which is was
designed.
Primitive Testing: println
Console IO to observe actual behavior
Compare IO with expected output
See TestRandom
Advantages:
Simple, easy, intuitive
Problems:
Exhaustive testing means lots of output
Comparison is tiresome and error-prone
Difficult to automate
Do it by Unit
We highlight Unit Testing because it is:
most common type of testing in application
software development.
module-wise testing fits with module-wise
development.
effective when applied with principles and
supporting tools we present.
JUnit Testing Framework
xUnit Family of testing languages (CUnit, cppUnit,
XMLUnit, dbUnit)
Provides API for creating repeatable unit.
tests with clear pass/fail result
Lightweight, intuitive, and easy to use.
De-facto standard for unit testing in Java
Large community of developers use it
• BlueJ, JBuilder, and Eclipse now provide JUnit
tools
Structure of a JUnit test class
Suppose you want to test a class named Math
public class MathTest
extends [Link] {
– This is the unit test for the Math class; it declares (and possibly defines)
values used by one or more tests
public MathTest() { }
– This is the default constructor
protected void setUp()
– Creates a test fixture by creating and initializing objects and values.
protected void tearDown()
– Releases any system resources used by the test fixture
public void testAdd(), public void testMultiply(), etc.
– These methods contain tests for the Fraction methods add(), multiply(),
etc. (note how capitalization changes)
Test your object, and verify the actual values returned with
assertEquals()
Assertions
Different kinds of tests
Static methods of [Link]
AssertEquals (message, expected, actual);
AssertTrue (message, condition);
AssertFalse (message, condition);
AssertNull (message, object);
AssertNotNull (message, object);
AssertSame (message, object);
AssertNotSame (message, object);
Fail (message);
Test Suite
Obviously you have to test your code to get it
working in the first place
– You can do ad hoc testing (running whatever tests
occur to you at the moment), or
– You can build a test suite (a thorough set of tests that
can be run at any time)
Contain Test Cases and/or other Test Suites.
Default Test Suite contains all tests
Generally explicitly defined to allow running subsets of tests.
Test Suites
Disadvantages of a test suite
– It’s a lot of extra programming
This is true, but use of a good test framework can help quite a bit
– You don’t have time to do all that extra work
False--Experiments repeatedly show that test suites reduce
debugging time more than the amount spent building the test suite
Advantages of a test suite
– Reduces total number of bugs in delivered code
– Makes code much more maintainable and
refactorable
This is a huge win for programs that get actual use!
Traffic Light example
public class TLight {
String state;
public TLight() { state=“RED”; }
public String getState() { return state; }
public void next() {
if ([Link] (“RED”))
state=“GREEN”;
else if ([Link] (“GREEN”))
state=“YELLOW”;
else
state=“RED”;
}
}
Traffic Light example (2)
public class testLight extends TestCase {
public void testTransitions() {
TLight tl = new TLight();
[Link]();
assertEquals (“GREEN”, [Link]());
[Link]();
assertEquals (“YELLOW”,[Link]());
}
}
Test Suite
public static Test suite() {
TestSuite suite = new TestSuite ("Test for
package name");
//$JUnit-BEGIN$
[Link] ([Link]);
//$JUnit-END$
return suite;
}
More JUnit
Multiple tests in class?
Just create more methods starting with
test
Allocating / Deallocating test resources?
Override setUp() and tearDown() methods
Ex: creating and closing database
connection
Good Practice: Comparing Floats
Never compare floating point numbers
directly for equality
AssertEquals (“Low-density experiment”,
1.456, calculated);
Numeric instabilities make exact equality
problematic
Better approach: Equality with tolerance
AssertEquals (“Low-density experiment”,
1.456, calculated, 0.001);
Testing State
Typical unit tests pass some data to an
object being tested, and some return value
is verified.
Here we are testing object state
Although this is straightforward, it has some
disadvantages in testing real applications
Testing State - downsides
Too many dependencies
High setup and teardown cost, very difficult to
pinpoint where bugs originate
Too much exposure
To verify state of an object, we often have to
look into its implementation
- We should be concerned with what an object does, but not how
it does it.
JUnit + Eclipse IDE
Download [Link] from [Link].
Put it in the Project Java Build Path.
Start Writing Test Cases.
Test Case In Eclipse
New > JUnit Test Case
First screen of wizard:
Checkbox “New JUnit Test Case”
Enter name of test class (eg. ThingTest)
Enter name of “class under test” (eg. Thing)
If warning “JUnit not on build path” appears,
click link to add it to build path
Second screen of wizard:
Select methods to test.
Generates one test case / selected method
But you will need many more than that
To run, Run As… > JUnit Test
Test Suite in Eclipse
New > JUnit Test Suite.
First screen of wizard:
Enter name of test suite (eg. AllTest)
Select test Classes to add (eg. TestMath)
If warning “JUnit not on build path” appears,
click link to add it to build path
To run, Run As… > JUnit Test
Running Test Cases
Eclipse features a JUnit view.
Provides an informative GUI displaying test
summaries.
Lets you edit the code, compile and test
without leaving the Eclipse environment.
TestCase Failure…
TestCase Success…
Problems with unit testing
Works great for methods that just return results, but
many methods have side effects
To test methods that do output, you have to capture the output
To test methods that change the state of the object, you have to
have code that checks the state
– It isn’t easy to see how to unit test GUI code
JUnit encourages a “functional” style, where most
methods are called to compute a value, rather than to
have side effects
– This can actually be a good thing
– Methods that just return results, without side effects (such as
printing), are simpler, more general, and easier to reuse
How do we Test our Tests?
Recall that a primary goal of testing is to
efficiently cover the state-space with tests.
Test Coverage measures the effectiveness of
your tests.
Types of Test Testing
Basic
Call Coverage
Branch Coverage
Statement Coverage
Condition Coverage
Multiple Condition Coverage
Loop Coverage
Path Coverage
Advanced
Clover
Reports Test Coverage by
Statement Coverage
Call Coverage
Branch Coverage
Uses Source Code Instrumentation
Duplicates and modifies source code,
requires separate compilation.
Traffic Light Example
Supplemental Reading
JUnit web site
[Link]
See “Getting Started”
JUnit FAQ
[Link]
JUnit cookbook
[Link]
Summary
Nature of testing
Specification, implementation, test cases
Return only copies of fields (reference types)
JUnit overview
Test case: method with test+MethodName
Test fixture: class collecting common tests
Test suite: set of fixtures
Assertions
Execution model
Multiple instantiation of test class
Independence of test cases
No ordering guarantee
Conclusion
Unit testing is a valuable tool in eliminating SW
defects in the development cycle
Tools like JUnit allow us to test much earlier in
the development cycle
Just as JUnit improves our code quality, Clover
improves our test quality
By showing how much of our code base our tests actually
cover
Queries ???