Software Engineering Requirements Engineering

Download Report

Transcript Software Engineering Requirements Engineering

Unit Testing with JUnit

CS 3331 Fall 2009 Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests,

Java Report

, 3(7):37-50, 1998.

Available from: http://junit.sourceforge.net/doc/testinfected/testing.htm

1

Unit Testing

 Introduction  Conventional approach  Unit testing with JUnit  More on JUnit 2

Testing in General

  Testing  A way of showing the correctness of software Phases  Unit testing  To test each module (unit, or component) independently    Mostly done by developers of the modules Integration and system testing  To test the system as a whole  Often done by separate testing or QA team Acceptance testing  To validate system functions for (and by) customers or user 3

What Is Unit Testing?

 Definition 

Testing

is the process of showing that a program works for certain inputs.

A unit

is a module or a small set of modules.

 In Java, a unit is a class or interface, or a set of them, e.g.,  An interface and 3 classes that implement it, or  A public class along with its helper classes.

Unit testing

is testing of a unit.

4

Question

 Do you get more confidence by running more test data?

5

Why Unit Testing?

  

Code isn’t right if it’s not tested

.

Practical  Most programmers rely on testing, e.g.,  Microsoft has 1 tester per developer.

You could get work as a tester.

Divide-and-conquer approach  Split system into units.

   Debug unit individually.

Narrow down places where bugs can be.

Don’t want to chase down bugs in other units.

6

Why Unit Testing? (Cont.)

 Support regression testing  So can make changes to lots of code and know if you broke something.

 Can make big changes with confidence.

7

How to Do Unit Testing

 Build systems in layers  Starts with classes that don’t depend on others.

 Continue testing building on already tested classes.

 Benefits  Avoid having to write (test) stubs.

 When testing a module, ones it depends on are reliable.

8

Question

 How does low coupling help testing?

 How does high coupling hurt it?

9

Program to Test

public final class IMath { } } /** * Returns an integer approximation to the square root of x. */ public static int isqrt(int x) { int guess = 1; while (guess * guess < x) { guess++; } return guess; 10

Conventional Testing

/** A class to test the class IMath. */ public class IMathTestNoJUnit { /** Runs the tests. */ public static void main(String[] args) { printTestResult(0); printTestResult(1); printTestResult(2); printTestResult(3); printTestResult(4); printTestResult(7); printTestResult(9); printTestResult(100); } } private static void printTestResult(int arg) { System.out.print(“isqrt(“ + arg + “) ==> “); System.out.println(IMath.isqrt(arg)); } 11

Conventional Test Output

Isqrt(0) ==> 1 Isqrt(1) ==> 1 Isqrt(2) ==> 2 Isqrt(3) ==> 2 Isqrt(4) ==> 2 Isqrt(7) ==> 3 Isqrt(9) ==> 3 Isqrt(100) ==> 10   What does this say about the code? Is it right?

What’s the problem with this kind of test output?

12

Solution?

 Automatic verification by testing program  Can write such a test program by yourself, or  Use a testing tool such as JUnit.

 JUnit  A simple, flexible, easy-to-use, open-source, and practical unit testing framework for Java.

 Can deal with a large and extensive set of test cases.

 Refer to www.junit.org.

13

Testing with JUnit

import junit.framework.*; /** A JUnit test class to test the class IMath. */ public class IMathTest extends TestCase { } /** Tests isqrt. */ public void testIsqrt() { assertEquals(0, IMath.isqrt(0)); // line 23 assertEquals(1, IMath.isqrt(1)); assertEquals(1, IMath.isqrt(2)); assertEquals(1, IMath.isqrt(3)); assertEquals(2, IMath.isqrt(4)); assertEquals(2, IMath.isqrt(7)); assertEquals(3, IMath.isqrt(9)); assertEquals(10, IMath.isqrt(100)); 14

Testing with JUnit (Cont.)

/** Returns the test suite for this test class. */ } public static Test suite() { return new TestSuite(IMathTest.class); } } /** Run the tests. */ public static void main(String[] args) { junit.textui.TestRunner.run(suite()); // junit.swingui.TestRunner.run(suite()); 15

Compilation and Output

$ javac IMath.java IMathTest.java

$ java IMathTest .F

Time: 0.02

There was 1 failure: 1) testIsqrt(IMathTest)junit.framework.AssertionFailedError: expected:<0> but was:<1> at IMathTest.testIsqrt(IMathTest.java:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMeth...

at sun.reflect.Delegating...

at IMathTest.main(IMathTest.java:17) FAILURES!!!

Tests run: 1, Failures: 1, Errors: 0 Question: Is this better? Why?

16

Exercise

 Write a JUnit test class for testing } public class ForYou { /** Return the minimum of x and y. */ public static int min(int x, int y) { ... } 17

Exercise (Cont.)

By filling in the following: import junit.framework.*; /** Test ForYou. */ public class ForYouTest extends TestCase { /** Test min. */ public void testMin() { } public class ForYou { /** Return the minimum of x and y. */ public static int min(int x, int y) { ... } } } // the rest as before … 18

Some Terminology

  Definition  A

test data

(or

case

) for a method M is a pair of (o, args), where   o is not null and M can be sent to o, args is a tuple of arguments that can be passed to M.

  A test data, (o, args), for M

succeeds

behaves as expected.

A test data, (o, args), for M as expected.

fails

iff o.M(args) iff it does not behave Question   Why should o not be null?

If M has a bug that is revealed by a test data, does that test data for M succeeds or fails?

19

Parts of Test Code

 Definition   The

test fixture

is the set of variables used in testing.

The

test driver

is the class that runs the tests.

 The

test oracle

for a test data is the code that decides success or failure for that test data.

 Question   What in the code we saw so far was the test driver, and the oracle?

What difference is there between JUnit testing and non-JUnit testing in what we saw before?

20

Basic Usage of JUnit

To test a type T: 1. Write a class like: import junit.framework.*; /** A JUnit test class for the class T. */ public class TTest extends TestCase { /** Runs the tests. */ } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } /** Returns the test suite for this test class. */ public static Test suite() { return new TestSuite(TTest.class); } <

test methods go here

> 21

Basic Usage of JUnit (Cont.)

2. Compile T.java and TTest.java

$ javac T.java TTest.java

3. Run the JUnit graphical user interface on TTest $ java junit.swingui.TestRunner TTest or Run the text interface (good from makefiles) $ java TTest 4. Look at the failures and errors 22

Naming Convention

 Test methods start with “test” e.g., testIsqrt, testMin  Test classes end with “Test” e.g., IMathTest, ForYouTest 23

Assertion Methods

Method assertEquals(a,b) assertFalse(a) assertNotSame(a, b) assertNull(a) assertSame(a,b) assertTrue(a) Description Test if a is equal to b Test if a is false Test if a and b do not refer to the identical object Test if a is null Test if a and b refer to the identical object Test if a is true - Static methods defined in junit.framework.Assert

- Variations taking string error messages 24

More on JUnit -- Test Fixture

 Sharing test data among test methods public class TTest extends TestCase { // other

methods here

… } protected void setUp() throws Exception { // initialize test fixture variables.

} protected void tearDown() throws Exception { // uninitialize test fixture variables.

} // test fixture variables, i.e., fields shared by several test methods.

25

Example

public class PointTest extends TestCase { private Point p; // test fixture variable } protected void setUp() { // initializes text fixture variables p = new Point(10, 10); protected void tearDown() { } // clean up text fixture variables } public void testSetX() { // tests SetX p.setX(20); assertEquals(20, p.getX()); } public void testSetY() { // tests SetY p.setY(30); assertEquals(30, p.getY()); } // template and other test methods here… 26

More on JUnit -- Test Suite

 Definition  A

test suite

test suites.

is a set of test methods and other  Test Suite  Organize tests into a larger test set.

 Help with automation of testing.

27

Example

public class AllTestSuite extends TestCase { } /** Returns the test suite for this test class. */ public static Test suite() { TestSuite suite = new TestSuite() { public String toString() { return "Test suite for Project T"; } }; suite.addTestSuite(T1Test.class); suite.addTestSuite(T2Test.class); … suite.addTestSuite(TnTest.class); return suite; } // the rest of methods as before … 28

More on JUnit?

 Refer to www.junit.org

 JUnit APIs available from the course Web page 29