You are on page 1of 58

• J UNIT FRAMEWORK

•  
• Automatic Tests - Goal -Fixtures-Testing Exceptions -
Junit's Implementation - Junit API - Test First
Programming - Stub - Other Uses for Tests - Extending
Junit - Junit and Ant - Running Junit Standalone
•  
• - Junit and IDEs. (10)
Unit Testing
• Testing the internals of a class

• Black box testing


• Test public methods

• Classes are tested in isolation


• One test class for each application
class
What is TDD?
• TDD is a technique whereby you write your test
cases before you write any implementation code

• Tests drive or dictate the code that is developed

• An indication of “intent”
• Tests provide a specification of “what” a piece of
code actually does
• Some might argue that “tests are part of
the documentation”

3
Test First vs. Test Last

[1] [1]
TDD Benefits (1 of 3)
• Instant Feedback
– Developer knows instantly if new code works and if it
interferes with existing code [1]
• Better Development Practices
– Encourages the programmers to decompose the
problem into manageable, formalized programming
tasks [1]
– Provides context in which low-level design decisions
are made [1]
– By focusing on writing only the code necessary to pass
tests, designs can be cleaner and clearer than is often
achieved by other methods [4]
TDD Benefits (2 of 3)
• Quality Assurance
– Having up-to-date tests in place ensures a
certain level of quality [1]
– Enables continuous regression testing [2]
– TDD practices drive programmers to write code
that is automatically testable [2]
– Whenever a software defect is found, unit test
cases are added to the test suite prior to fixing
the code [2]
TDD Benefits (3 of 3)
• Lower Rework Effort
– Since the scope of a single test is limited, when
the test fails, rework is easier
– Eliminating defects early in the process usually
avoids lengthy and tedious debugging later in
the project [4]
– “Cost of Change” is that the longer a defect
remains the more difficult and costly to remove
[3]
Junit
• JDK 1.4 provides an assertion feature ( which
enables you to test (or assert) your
assumptions about your program logic (such
as pre-conditions, post-conditions, and
invariants).
• assertion is primitive compared with the unit
testing framework.
Junit Framework
• JUnit test framework provides the following important features −
• Fixtures
• Test suites
• Test runners
• JUnit classes

• Fixtures is a fixed state of a set of objects used as a baseline for


running tests. The purpose of a test fixture is to ensure that there
is a well-known and fixed environment in which tests are run so
that results are repeatable. It includes −
• setUp() method, which runs before every test invocation.
• tearDown() method, which runs after every test method.
• Test Fixtures, @Before and @After
• A test fixtures is a fixed state of a set of objects used as a baseline
for running tests. The purpose of a test fixture is to ensure that
there is a well known and fixed environment in which tests are run
so that results are repeatable.
• In JUnit 4, fixtures are setup via
the @Before and @After annotations.
• The @Before annotated method (known as setup()) will be run
before EACH test method (annotated with @Test) to set up the
fixtures.
• The @After annotation method (known as tearDown()) will be run
after EACH test.
• We typically declare text fixtures as private instance variables;
initialize via @Before annotated method; and clean-up
via @After annotation method. Each test method runs on its
own set of text fixtures with the same initial states. This
ensures isolation between the test methods.
• @BeforeClass and @AfterClass
• Beside the @Before and @After, there is
also @BeforeClass and @AfterClass.
• The @BeforeClass annotated method will be run once before
any test, which can be used to perform one-time initialization
tasks such as setting up database connection.
• The @AfterClass annotated method will be run once after all
tests, which can be used to perform housekeeping tasks such
as closing database connection.
import junit.framework.*;
 
public class JavaTest extends TestCase {
protected int value1, value2;

// assigning the values


protected void setUp(){
value1 = 3;
value2 = 3;
}
// test method to add two values
public void testAdd(){
double result = value1 + value2;
assertTrue(result == 6);
}
}
• Test Suites
• A test suite bundles a few unit test cases and
runs them together. In JUnit, both @RunWith
and @Suite annotation are used to run the
suite test. Given below is an example that uses
TestJunit1 & TestJunit2 test classes.
• import org.junit.runners.Suite; 
• //JUnit Suite Test
• @RunWith(Suite.class) 
• @Suite.SuiteClasses({
• TestJunit1.class ,
• TestJunit2.class}) 
• public class JunitTestSuite
• {
• }
• Test Runners
• Test runner is used for executing the test
cases. Here is an example that assumes the
test class TestJunit already exists.
• JUnit Classes
• JUnit classes are important classes, used in
writing and testing JUnits. Some of the important
classes are −
• Assert − Contains a set of assert methods.
• TestCase − Contains a test case that defines the
fixture to run multiple tests.
• TestResult − Contains methods to collect the
results of executing a test case.
TDD Stages
1. Write a single test.
2. Compile it. It should not compile because you
have not written the implementation code
3. Implement just enough code to get the test to compile
4. Run the test and see it fail
5. Implement just enough code to get the test to pass
6. Run the test and see it pass
7. Refactor for clarity and “once and only once”
8. Repeat
19
TDD Stages
Write a test

Refactor
Compile
code (and
test)

Run test,
Fix compile errors
watch it
pass

Run test,
Write code
watch it
fail

20
Why TDD?
• Programmers dislike testing
• They will test reasonably thoroughly the first time
• The second time however, testing is usually less thorough
• The third time, well..
• Testing is considered a “boring” task
• Testing might be the job of another department / person
• TDD encourages programmers to maintain an exhaustive
set of repeatable tests
• Tests live alongside the Class/Code Under Test (CUT)
• With tool support, tests can be run selectively
• The tests can be run after every single change

21
Summary
• TDD does not replace traditional testing
• It defines a proven way that ensures effective unit
testing
• Tests are working examples of how to invoke a piece
of code
• Essentially provides a working specification for the
code

• No code should go into production unless it


has associated tests
• Catch bugs before they are shipped to your
customer

• No code without tests

22
• Tests determine, or dictate, the code
Summary
• TDD means less time spent in the debugger

• TDD negates fear


• Fear makes developers communicate less
• Fear makes developers avoid repeatedly testing
code
• Afraid of negative feedback

23
Summary
• TDD promotes the creation of a set of
“programmer tests”
• Automated tests that are written by the programmer
• Exhaustive
• Can be run over and over again

• TDD allows us to refactor, or change the


implementation of a class, without the fear of breaking
it
• TDD and refactoring go hand-in-hand

• With care, [some] User Acceptance Tests can


be codified and run as part of the TDD
24 process
Resources
• JUnit:
http://junit.sourceforge.net

• NUnit: http://www.nunit.org

• CSUnit: http://www.csunit.org

25
XP approach to testing

• In the Extreme Programming approach


• Tests are written before the code itself
• If the code has no automated test cases, it is
assumed not to work
• A testing framework is used so that automated testing can
be done after every small change to the code
• This may be as often as every 5 or 10 minutes
• If a bug is found after development, a test is created to keep
the bug from coming back

26
XP consequences
• Fewer bugs
• More maintainable code
• The code can be refactored without fear
• Continuous integration
• During development, the program always works
• It may not do everything required, but what it does, it
does right

27
28
Figure Test-first process in XP
Unit Testing in eXtreme Programming

1. Pick a requirement, i.e., a story


2. Write a test case that will verify a small
part of the story and assign a fail verdict
to it
3. Write the code that implement particular
part of the story to pass the test
4. Execute all test
5. Rework on the code, and test the code
until all tests pass
6. Repeat step 2 to step 5 until the story is
fully implemented
29
Unit Testing in eXtreme Programming

Three laws of Test Driven


development (TDD)
• One may not write production
code unless the first failing unit
test is written
• One may not write more of a unit
test than is sufficient to fail
• One may not write more
production code than is sufficient
to make the failing unit test pass
Pair programming:
– In XP code is being developed by
two programmers working side by
side
– One person develops the code
tactically and the other one
inspects it methodically by
keeping in mind the story they are
implementing
30

• JUnit: It is a framework for


JUnit – A Framework for Unit Testing

performing unit testing of Java


programs.
– Other frameworks: NUnit (C#),
CPPUnit (C++), fUnit (Fortran)
• Intuitive steps to test a method in
Java (Ex. Move() method of
PlanetClass)
– Create an object instance of
PlanetClass. Call it Mars.
– Select values of all input parameters
of Move().
– Compute the expected value to be
returned by Move(). Let it be y.
– Execute method Move() on Mars
with the selected input values.
• Let Move() return a value called z.
– Compare the actual output (z)
returned by Move() with the expected
value (y).
• If (z == y), Move() passes the test;
otherwise it fails. Report the result.


• JUnit makes writing of test cases
easier. Next slide …


• JUnit provides a basic class called
31
JUnit – A Framework for Unit Testing

TestCase.
• The tester
– Extends the TestCase class for each
test case. 10 extensions for 10 test
cases.
– Alternatively, extend TestCase to have
10 methods for 10 test cases.
• The TestCase class provides
methods to make assertions.
– assertTrue(Boolean condition)
– assertFalse(Boolean condition)
– assertEquals(Object expected, Object
actual)
– assertEquals(int expected, int actual)
– assertEquals(double expected, double
actual, double tolerance)
– assertSame(Object expected, Object
actual)
– assertNull(Object testobject)
– …
• The tester can have her own
assertions.
32

• Each assertion accepts an


JUnit – A Framework for Unit Testing

optional first parameter of type


String; if the assertion fails, the
string is displayed. Help for

the tester…
• The assertEquals() method
displays a message upon failure.
• junit.framework.AssertionFailedErr
or: expected: <x> but was: <y>
• Note that only failed tests are
reported.
• The following shows how
assertTrue() works.
static public void assertTrue(Boolean condition) {
if (!condition)
throw new AssertionFailedError();
}
Figure 3.5: The assertTrue()
assertion throws an exception
33
JUnit – A Framework for Unit Testing

import TestMe; // TestMe is the class whose methods


are going to be tested.
import junit.framework.*; // This contains the
TestCase class.
public class MyTestSuite extends TestCase { //
Create a subclass of TestCase
public void MyTest1() { // This method is the first
test case
TestMe object1 = new TestMe( ... ); // Create
an instance of TestMe with desired params
int x = object1.Method1(...); // invoke
Method1 on object1
assertEquals(365, x); // 365 and x are
expected and actual values, respectively.
}
public void MyTest2() { // This method is the
second test case
TestMe object2 = new TestMe( ... ); // Create
another instance of
// TestMe with desired
parameters
double y = object2.Method2(...); // invoke
Method2 on object2
assertEquals(2.99, y, 0.0001d); // 2.99 is the
expected value;
// y is the actual value;
// 0.0001 is tolerance level
}
}
: An example test suite
JUnit
• JUnit is a framework for writing tests
• Written by Erich Gamma (of Design Patterns
fame) and Kent Beck (creator of XP
methodology)
• Uses Java features such as annotations and
static imports
• JUnit helps the programmer:
• define and execute tests and test suites
• formalize requirements
• write and debug code
• integrate code and always be ready to release a
working version

34
Terminology
• A test fixture sets up the data (both objects
and primitives) that are needed for every
test
• Example: If you are testing code that updates an
employee record, you need an employee record
to test it on
• A unit test is a test of a single class
• A test case tests the response of a
single method to a particular set of
inputs
• A test suite is a collection of test cases

35
• A test runner is software that runs tests
and reports results
Structure of a JUnit test class
• To test a class named Fraction
• Create a test class
FractionTest
import org.junit.*;
import static
public org.junit.Assert.*;
{ class FractionTest

} …

36
Test fixtures
• Methods annotated with @Before will execute
before every test case
• Methods annotated with @After will execute after
every test case

@Before
public void setUp()
{…}
@After
public void tearDown() {…}

37
Class Test fixtures
• Methods annotated with @BeforeClass will
execute once before all test cases
• Methods annotated with @AfterClass will
execute once after all test cases
• These are useful if you need to allocate and
release expensive resources once

38
Test cases
• Methods annotated with @Test are considered to
be test cases

@Test
public void testadd()
@Test {…}
public void testToString()
{…}

39
What JUnit does
• For each test case t:
• JUnit executes all @Before methods
• Their order of execution is not
specified
• JUnit executes t
• Any exceptions during its execution
are logged
• JUnit executes all @After methods
• Their order of execution is not
specified
• A report for all test cases is presented

40
Within a test case

• Call the methods of the class being tested


• Assert what the correct result should be
with one of the provided assert methods
• These steps can be repeated as many times as
necessary
• An assert method is a JUnit method that
performs a test, and throws an
AssertionError if the test fails
• JUnit catches these exceptions and shows you the results

41
List of assert methods 1
• assertTrue(boolean b)
assertTrue(String s, boolean
b)
• Throws an AssertionError if b is False
• The optional message s is included in
the Error
• assertFalse(boolean b)
assertFalse(String s, boolean
b)
• Throws an AssertionError if b is True
• All assert methods have an optional
message

42
Example: Counter class
• Consider a trivial “counter” class
• The constructor creates a counter and sets it to zero
• The increment method adds one to the counter
and returns the new value
• The decrement method subtracts one from the
counter and returns the new value
• An example and the corresponding JUnit test class
can be found on the course website

43
List of assert methods 2
• assertEquals(Objec expected
t ,
Object actual)
• Uses the equals method to compare the
two objects
• Primitives can be passed as arguments
thanks to autoboxing
• Casting may be required for primitives
• There is also a version to compare arrays

44
List of assert methods 4
• assertNull(Object object)
Asserts that a reference is null
• assertNotNull(Object object)
Asserts that a reference is not null
• fail()
Causes the test to fail and throw an AssertionError
• Useful as a result of a complex test, or when
testing for exceptions

45
Testing for exceptions
• If a test case is expected to raise an exception, it can
be noted as follows

@Test(expected = Exception.class)
public void testException() {
//Code that should raise an
exception
fail("Should raise an exception");
}

46
The assert statement
• A statement such as
assert
boolean_condition; will also
throw an AssertionError if the
boolean_condition is false
• Can be used instead of the Junit
assertTrue method

47
Ignoring test cases
• Test cases that are not finished yet can be
annotated with @Ignore
• JUnit will not execute the test case but will report
how many test cases are being ignored

48
JUnit in Eclipse
• JUnit can be downloaded
from
http://junit.sourceforge.net/
• If you use Eclipse, as in this course, you do not need
to download anything
• Eclipse contains wizards to help with the development
of test suites with JUnit
• JUnit results are presented in an Eclipse window

49
Hello World
demo
• Run Eclipse
• File -> New -> Project, choose Java Project,
and click Next. Type in a project name, e.g.
ProjectWithJUnit.
• Click Next
• Click Create New Source Folder, name it test
• Click Finish
• Click Finish

50
Create a class
• Right-click on
ProjectWithJUnit Select New
-> Package
Enter package name, e.g.
cse2311.week2
Click Finish
• Right-click on
cse2311.week2 Select New
-> Class
Enter class name, e.g.
HelloWorld
Click Finish

51
Create a class - 2
• Add a dummy method such as
public String say() { return
null; }
• Right-click in the editor window
and select Save

52
Create a test class
• Right-click on the HelloWorld
class Select New -> Junit Test
Case
• Change the source folder to test as opposed
to src

53
Create a test class
• Check to create a setup method
• Click Next
• Check the checkbox for the say
method
• This will create a stub for a test case for this
method

• Click Finish
• Click OK to “Add JUnit 4 library to the
build path”
• The HelloWorldTest class is created
• The first version of the test suite is
ready
Run the test class - 1st try
• Right click on the HelloWorldTest class
• Select Run as -> JUnit Test
• The results appear in the left
• The automatically created test case
fails

55
Create a better test case
• Import the class under test
import cse2311.week2.HelloWorld;
• Declare an attribute of type HellowWorld
HelloWorld hi;
• The setup method should create a HelloWorld
object
hi = new HelloWorld();
• Modify the testSay method body to
assertEquals("Hello World!",
hi.say());

56
Run the test class - 2nd
try
• Save the new version of the test class and re-run
• This time the test fails due to expected and actual
not being equal
• The body of the method say has to be modified to
return(“Hello World!”);
for the test to pass

57
Create a test suite
• Right-click on the cse2311.week2 package in the
test source folder
• Select New -> Class. Name the class AllTests.
• Modify the class text so it looks like class AllTests on
the course website
• Run with Run -> Run As -> JUnit Test
• You can easily add more test classes

58

You might also like