#8 Junit Testing Framework
#8 Junit Testing Framework
#8 Junit Testing 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
• 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
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
22
• Tests determine, or dictate, the code
Summary
• TDD means less time spent in the debugger
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
• NUnit: http://www.nunit.org
• CSUnit: http://www.csunit.org
25
XP approach to testing
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
• 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
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
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
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