Unit Testing with JUnit - PowerPoint PPT Presentation

1 / 44
About This Presentation
Title:

Unit Testing with JUnit

Description:

Prevent re-introduction of faults (regression errors) ... import static names from 'Assert' public PurseTest { // don't extend TestCase ... – PowerPoint PPT presentation

Number of Views:212
Avg rating:3.0/5.0
Slides: 45
Provided by: JamesB128
Category:

less

Transcript and Presenter's Notes

Title: Unit Testing with JUnit


1
Unit Testing with JUnit
  • James Brucker

2
Many Levels of Software Testing
  • Unit Testing
  • Integration Testing
  • Acceptance Testing
  • Usability Testing
  • ...

3
Why Test?
  • Saves time!
  • Testing is more efficient than debugging.
  • Prevent re-introduction of faults (regression
    errors)
  • Validate software does it match the
    specification?

4
Testing is part of development
  • Agile Development philosophy
  • Test early.
  • Test continually!
  • Design
  • Test
  • Code
  • Test
  • Code
  • Test
  • Design
  • Test
  • Code
  • Test-driven Development
  • Many programmers write test cases first, then
    code.
  • provides insight goals.

5
Unit Testing
  • Test each method of each class
  • Test while you are writing the source code
  • Retest whenever you modify the source code
  • Agile programming recommends
  • Write the test cases first!

6
The Cost of Fixing "faults"
  • Discover fix a defect early is much cheaper
    (100X) than to fix it after code is integrated.

Figure 1.5
7
The Cost of Change
  • The previous figure drawn on a linear scale

Figure 1.6
8
An Example
  • A Coin Purse holds 1, 5, and 10 Baht coins.
  • It has a capacity that is fixed when the purse is
    created.
  • capacity is the number of coins (any type) that
    purse can hold
  • You can insert and withdraw coins within
    capacity.

insertCoin returns true if coin inserted.
9
Testing without JUnit
Purse purse new Purse(10) // can hold 10
coins purse.insertCoin( new Coin( 10 ) ) if (
purse.isFull() ) out.println("ERROR
full") balance purse.getBalance( ) if (
balance ! 10 ) out.println("ERROR balance is
wrong" ) if ( purse.withdraw(5) ! null )
out.println("ERROR withdraw is wrong") if (
purse.isFull() ) out.println("ERROR is
full") if ( purse.withdraw(10) null )
out.println("ERROR couldn't withdraw 10 Baht")
10
Structure of a Test Class
Class in Your Project Test Class
public class Purse / create coin purse
/ public Purse(int capacity) ... /
insert coins / public boolean insertCoins(
int tens, int fives, int ones) ... /
get value of purse / public int getBalance( )
...
public class PurseTest / test the
constructor / public void testPurse( )
... /test insert coins / public void
testInsertCoin() ... / test get value
of purse / public void testGetBalance( )
...
11
Example test Purse constructor
import org.junit. // This is for JUnit
4 public PurseTest / test the constructor
/ _at_Test // _at_Test identifies a test
method public void testPurse( ) // any public
void method Purse p new Purse( 10 ) //
capacity 10 Assert.assertEquals("New Purse
should be empty", 0, p.count() ) Assert.assert
Equals("Capacity should be 10", 10,
p.getCapacity() )
optional message to print if test fails
expected result
actual result
12
Example test insertCoin method
import org.junit. public PurseTest /test
insert coins / _at_Test public void insertCoins()
Purse purse new Purse( 10 ) // capacity
10 boolean result p.insertCoin( new Coin( 5 )
) Assert.assertTrue("Couldn't add coins!",
result ) Assert.assertEquals( "Balance wrong",
5, purse.getBalance( ) ) Assert.assertFalse(
"Not full yet!", purse.isFull( ) )
13
JUnit 4
  • JUnit 4 uses annotations to identify methods
  • _at_Test indicates a test method
  • _at_Before indicates a setUp method
  • _at_After indicates a tearDown method
  • package to import org.junit.
  • Differences from JUnit 3.x
  • your class doesn't need to extend TestCase
  • don't need to create a TestSuite
  • methods can use any names

14
Contents of a Test Class (JUnit 4.x)
import org.junit.Test // JUnit 4 uses package
org.junit import static org.junit.Assert. //
import static names from "Assert" public
PurseTest // don't extend TestCase / test
the constructor / _at_Test // use _at_Test
annotation public void testPurse( ) // any
void method - no parameters Purse p new
Purse( 10 ) // capacity 10 assertEquals("New
Purse should be empty", 0, p.count()
) assertEquals("Capacity should be 10", 10,
p.capacity() ) /test insert coins
/ _at_Test public void testInsertCoins()
Purse p new Purse( 10 ) // capacity
10 boolean result p.insertCoin( new Coin( 5 )
) assertTrue("Couldn't insert coins!", result
)
15
Before and After methods
_at_Before designates a method to run before each
test _at_After designates a method to run after each
test
import org.junit.Test // JUnit 4 uses package
org.junit import org.junit.Before import
org.junit.After import static org.junit.Assert.
// import names from JUnit4 "Assert" public
PurseTest // don't extend TestCase private
Purse purse _at_Before public void
runBeforeTest( ) purse new Purse( 10 )
_at_After public void runAfterTest( ) purse
null _at_Test public void testPurse( )
Assert.assertEquals("New Purse should be
empty", 0, purse.count() ) Assert.assertEquals("
Capacity should be 10", 10, purse.capacity() )
16
Running JUnit 4
  • CLASSPATHc/java/junit4.1/junit-4.1.jar.
  • java org.junit.runner.JUnitCore PurseTest

17
What can you Assert ?
  • JUnit Assert class provides many assert methods

Assert.assertTrue( aBoolean ) Assert.assertTrue(
"Error message", aBoolean )
Examples
// balance should be non-negative balance
purse.getBalance( ) Assert.assertTrue( "Balance
can't be negative!", balancegt0) // should
be able to withdraw 5 Baht Money money
purse.withdraw( 5 ) Assert.assertFalse(
"withdraw should succeed", moneynull )
18
AssertEquals
  • Assert.assertEquals is polymorphic

assertEquals( expected, actual ) assertEquals(
"Error message", expected, actual )
can be any primitive data type, String, or Object
// test the getBalance method purse new Purse(
10 / capacity / ) int balance
purse.getBalance( ) assertEquals( "Purse should
be empty", 0, balance ) purse.insertCoins( new
Money(0,0,5) ) balance purse.getBalance(
) assertEquals( "Balance is wrong", 50, balance
)
19
AssertEquals for Floating Point
  • assertEquals for float and double requires a
    tolerance ... an allowance for rounding errors

double root2 Math.sqrt( 2.0 ) Assert.assertEqu
als( 1.41421356, root2, 1.0E-8 )
ExpectedResult
ActualResult
Tolerance for comparison
20
More Asserts... see the Javadoc
import static org.junit.Assert. public class
PurseText extends TestCase public void
getInstance( ) purse.insertCoin( new Coin(5)
) Coin m1 purse.withdraw( 5
) assertNotNull("withdraw returned null", m1
) purse.insertCoin( new Coin(10) ) // does
withdraw re-use same array? (bad) Coin m2
Store.withdraw( 10 ) assertNotSame("withdraw
returned same array", m1, m2 )
21
setUp to do before each test
  • in the coin purse tests, every test creates a
    Purse()
  • this makes writing tests long and boring.

public void testPurse( ) Purse p new
Purse( 10 ) // new purse with capacity
10 Assert.assertEquals("New Purse should be
empty", 0, p.count() ) Assert.assertEquals("Cap
acity should be 10", 10, p.capacity()
) /test insert coins / public void
testInsertCoin() Purse p new Purse( 10 )
// new purse with capacity 10 boolean result
p.insertCoin( new Coin( VALUE )
) Assert.assertTrue("Couldn't insert coins!",
result )
22
setUp and tearDown
  • setUp - a method that is run before every test
    case.
  • tearDown - a method that is run after every test
    case.

setUp( )
testFun1( )
one test case
tearDown( )
setUp( )
another test case
testFun2( )
tearDown( )
23
setUp to do before each test
  • setUp( ) method is invoked before every test.
  • use setUp for repetitive tasks initializing
    objects vars.

public PurseTest extends TestCase private
Purse purse private static int CAPACITY
10 _at_Before protected void setUp( ) throws
Exception super( ) // always call super()
first purse new Purse( CAPACITY ) public
void testPurse( ) Assert.assertEquals("New
Purse should be empty", 0, purse.count()
)
setUp creates a new Purse for test
24
Expecting an Exception?
  • you can indicate that a test should throw an
    exception

// this should throw a PurseFullException _at_Test(
expectedpurse.PurseFullException.class
) protected void testPurseFull() Purse p
new Purse( 1 ) p.insertCoin( new Coin(5)
) p.insertCoin( new Coin(1) ) // should
overflow
25
Limit on Execution Time
  • you can specify a time limit (milliseconds) for a
    test
  • if time limit is exceeded, test fails

// this test should complete in // less than
200 milliseconds _at_Test( timeout200 ) protected
void testWithdraw() // purse and money
inserted by _at_Before method // now test if
withdraw completes on time purse.withdraw( 99
)
26
tearDown to do after each test
  • use tearDown for clean-up after each test

public PurseTest extends TestCase private
Purse purse private static int CAPACITY
10 _at_After protected void tearDown( ) throws
Exception super( ) purse null
27
Questions about JUnit 4
  • Why use
  • import static org.junit.Assert.
  • How do you indicate a method is a test case?
  • How do you test if Math.sin(Math.PI/2) is 1 ???
  • How do you test if scanner.hasNext() is true ???

28
Using JUnit in Eclipse
  • Eclipse includes JUnit 3.8 and 4.0 libraries
  • you don't need to install JUnit separately.
  • you don't need a TestSuite or main() either!
  • Eclipse will manage the testing.
  • Select a source file to test and then...

29
Using JUnit in Eclipse (2)
  • Select test options and methods to test.

30
Using JUnit in Eclipse (3)
/ Test of the Purse class _at_author James
Brucker / public class PurseTest private
Purse purse private static final int CAPACITY
10 / create a new purse before each test
/ _at_Before public void setUp() throws
Exception purse new Purse( CAPACITY )
_at_Test public void testCapacity()
assertEquals("capacity wrong",
CAPACITY, purse.capacity())
Write your test cases.Eclipse can't help much
with this.
31
Run JUnit in Eclipse (4)
Select the JUnit test case file and choose Run
gt Run As gt JUnit Test Results appear in a new
JUnit tab. Click on any result for details and to
go to the source code.
32
What and How to Test
  • Test constructors
  • Test methods that implement functionality
  • (usually) don't test trivial methods (getter,
    setter)
  • What conditions to test
  • "borderline" cases
  • if capacity is 10, can you insert 9, 10, 11
    coins?
  • can you withdraw 0 ?
  • can you withdraw exactly amount in the purse?
  • physically impossible
  • can you insert negative amounts?

33
JUnit 3.x
  • JUnit 3.x is really old. But a lot of existing
    software still uses it, so we need to know how to
    read JUnit 3.x test suites.
  • For new code, prefer the current version of JUnit.

34
Contents of a Test Class (JUnit 3.x)
import junit.framework. public PurseTest
extends TestCase / test the constructor
/ public void testPurse( ) Purse p new
Purse( 10 ) // new purse with capacity
10 Assert.assertEquals("New Purse should be
empty", 0, p.count() ) Assert.assertEquals("Capa
city should be 10", 10, p.getCapacity()
) /test insert coins / public void
testInsertCoins() Purse p new Purse( 10 )
// capacity 10 boolean result p.insertCoin(
new Coin( 5 ) ) result p.insertCoin( new
Coin( 10 ) ) Assert.assertTrue("Couldn't
insert coins", result ) Assert.assertEquals("Ba
lance is wrong", 5 10, p.getBalance()
) ...
35
Running The Tests in JUnit 3 (1)
  • For JUnit 3.8 your need a method a constructor
  • PurseTest( string ) constructor calls super(
    string )
  • suite( ) creates a test suite

import junit.framework. public PurseTest
extends TestCase public PurseTest( String
testmethod ) super( testmethod ) /
create a test suite automatically / public
static Test suite( ) TestSuite suite new
TestSuite( PurseTest.class ) return suite
This is standard form of the constructor just
copy it
36
Compiling and Running the Tests
  • You invoke a JUnit TestRunner to run your test
    suite.
  • JUnit 3.8 provides 3 test runners
  • junit.textui.TestRunner - console test runner
  • junit.awtui.TestRunner - graphical using AWT
  • junit.swingui.TestRunnger - graphical using Swing

gt set CLASSPATH /java/junit3.8.2/junit.jar. gt
javac PurseTest.java gt java junit.swingui.TestRunn
er PurseTest
Name of your test class as arg.
37
Another Way to Run Tests
  • Call test runner from your class's main method
  • don't need to invoke junit..TestRunner on cmd
    line

public PurseTest extends TestCase ... public
static void main( String args )
junit.swingui.TestRunner.run( PurseTest.class
)
gt set CLASSPATH /java/junit3.8.2/junit.jar. gt
javac PurseTest.java gt java PurseTest
Name of your test class as arg.
38
Selecting Tests to Run TestSuite
  • In the example we created a TestSuite using

public static Test suite( ) TestSuite suite
new TestSuite( PurseTest.class ) return
suite
JUnit uses reflection to locate all methods named
"test".
  • or can specify only the tests you want to run

only run these test methods
/ create a custom test suite / public static
Test suite( ) TestSuite suite new
TestSuite( ) suite.addTest( new PurseTest(
"testPurse" ) ) // test the constructor suite
.addTest( new PurseTest( "testInsertCoins") ) //
insert coins return suite
39
Key Points in Using JUnit 3.x
  • Your test class "extends TestCase"
  • import JUnit framework
  • import junit.framework.
  • optional import static names to reduce typing
  • import static junit.framework.Assert.
  • create void methods named "test____"
  • public void testGetBalance( )
  • ...
  • use assert commands to test expected results

40
Changes from Junit 3 to JUnit 4
This is a JUnit 4 test class. How is it different
from Junit 3?
import org.junit.Test import static
org.junit.Assert. public PurseTest /
test the constructor / _at_Test public void
Purse( ) Purse p new Purse( 10 ) //
capacity 10 Assert.assertEquals("New Purse
should be empty", 0, p.count() ) Assert.assertE
quals("Capacity should be 10", 10, p.capacity()
) /test insert coins / _at_Test public
void insertCoins() Purse p new Purse( 10 )
// capacity 10 boolean result p.insertCoins(
new Money(4, 3, 2) ) Assert.assertTrue("Couldn'
t add coins!", result )
41
JUnit 3 Adaptor for JUnit 4 test class
  • You can run JUnit 3 test cases using JUnit 4 ...

import org.junit.Test import static
org.junit.Assert. // import adaptor for
JUnit 3 import junit.framework.JUnit4TestAdaptor
public PurseTest // don't extend
TestCase / JUnit 3 calls suite( ) to get a
test suite / public static junit.framework.Test
suite( ) return new JUnit4TestAdaptor(
PurseTest.class ) _at_Test ... rest of the
JUnit 4 tests ...
42
Questions about JUnit 3
  • What are the 2 forms of every assert( )?
  • Why use
  • import static junit.framework.Assert.
  • What is the name of ...
  • the test class for "class LineItem" ?
  • your test class extends what other class?
  • the test method for the LineItem constructor?
  • the test method for the getItemID() method?

43
References
  • JUnit Home
  • http//www.junit.org
  • Getting software documentation
  • http//www.sf.net/projects/junit
  • Eclipse Netbeans include Junit, but you still
    need the javadoc for API
  • Quick Start
  • "JUnit Cookbook" (in JUnit "doc" directory)
  • "JUnit 4 in 10 Minutes" (on JUnit web site)

44
References
  • TestNG a better JUnit
  • http//www.testng.org
Write a Comment
User Comments (0)
About PowerShow.com