31
1 Unit Testing with JUnit CS 3331 JUnit website at http://www.junit.org 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 with JUnit CS 3331 JUnit website at Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

Embed Size (px)

Citation preview

Page 1: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

1

Unit Testing with JUnit

CS 3331

JUnit website at http://www.junit.org

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

Page 2: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

2

Unit Testing

Introduction Conventional approach Unit testing with JUnit More on JUnit

Page 3: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

3

Introduction Testing

A process of showing that a program works for certain inputs

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

Page 4: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

4

What Is Unit Testing? Testing focusing on the smallest units of code,

such as Functions, procedures, subroutines, subprograms Methods, classes

Component tested in isolation from the rest of the system and in a controlled environment: Uses appropriately chosen input data Uses component-level design description as guide

Unit testing is testing of a unit. Often the target of testing frameworks such as

JUnit

Page 5: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

5

Unit in Java?

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 A public class along with its helper classes.

Page 6: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

6

Question

Do you get more confidence by running more test data?

Page 7: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

7

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.

Page 8: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

8

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.

Page 9: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

9

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.

Page 10: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

10

Question

How does low coupling help testing? How does high coupling hurt it?

Page 11: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

11

Program to Test

public 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; }}

Page 12: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

12

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)); }}

Page 13: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

13

Conventional Test OutputIsqrt(0) ==> 1Isqrt(1) ==> 1Isqrt(2) ==> 2Isqrt(3) ==> 2Isqrt(4) ==> 2Isqrt(7) ==> 3Isqrt(9) ==> 3Isqrt(100) ==> 10

What does this say about the code? Is it right? What’s the problem with this kind of test output?

Page 14: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

14

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

Page 15: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

15

Testing with JUnitimport org.junit.Test;import static org.junit.Assert.*;

/** A JUnit test class to test the class IMath. */public class IMathTest {

/** Test isqrt. */ @Test public void testIsqrt() { assertEquals(0, IMath.isqrt(0)); // line 13 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)); }

Page 16: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

16

Testing with JUnit (Cont.)

/** Run the tests. */ public static void main(String[] args) { org.junit.runner.JUnitCore.main("IMathTest"); }}

Page 17: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

17

Compilation and Output$ javac IMath.java IMathTest.java$ java IMathTestJUnit version 4.10.ETime: 0.015There was 1 failure:1) testIsqrt(IMathTest) java.lang.AssertionError: expected:<0> but was:<1> at org.junit.Assert.fail(Assert.java:93) …

at IMathTest.main(IMathTest.java:13)

FAILURES!!!Tests run: 1, Failures: 1

Question: Is this better? If so, why?

Page 18: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

18

Exercise

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

Page 19: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

19

Exercise (Cont.)

public class ForYouTest { /** Test min. */ @Test public void testMin() {

} // the rest as before …}

public class ForYou { /** Return the minimum of x and y. */ public static int min(int x, int y) { ... }}

In Eclipse, - Select a source code folder - Right click (pop-up menu) - Select New > Other… > JUnit > Junit Test Case

Page 20: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

20

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 iff o.M(args) behaves as expected.

A test data, (o, args), for M fails iff it does not behave as expected.

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?

Page 21: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

21

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?

Page 22: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

22

Basic Usage of JUnitTo test a type T:

1. Write a class like:

import org.junit.*;import static org.junit.Assert.*;

/** A JUnit test class for the class T. */public class TTest { /** Runs the tests. */ public static void main(String[] args) { org.junit.runner.JUnitCore.main(“T") }

<test methods go here, e.g.,> @Test public void testM1() { … }}

Page 23: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

23

Basic Usage of JUnit (Cont.)

2. Compile T.java and TTest.java, e.g.,

$ javac T.java TTest.java

3. Run the JUnit in IDE such as Eclipse, e.g.,

Select Run As > JUnit Test

or

Run the text interface

$ java TTest

4. Look at the failures and errors

Page 24: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

24

Naming Convention

Test methods start with “test”

e.g., testIsqrt, testMin Test classes end with “Test”

e.g., IMathTest, ForYouTest

Page 25: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

25

Assertion Methods

Method Description

assertEquals(a,b) Test if a is equal to bassertFalse(a) Test if a is falseassertNotSame(a, b) Test if a and b do not refer to the

identical objectassertNull(a) Test if a is nullassertSame(a,b) Test if a and b refer to the identical

objectassertTrue(a) Test if a is truefail() Fail a test

- Static methods defined in org.junit.Assert- Variations taking string error messages

Page 26: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

26

Testing Exceptions

Use optional parameter “expected” of @Test annotation

Q: Without using “expected”?

@Test(expected=IndexOutOfBOundsException.class)public void indexingEmptyList() { new ArrayList<Object>().get(0);}

Page 27: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

27

More on JUnit -- Test Fixture

Sharing test data among test methods

public class TTest { // test fixture variables, i.e., fields shared by several test methods.

@Before public void setUp() throws Exception { // initialize test fixture variables. }

@After public void tearDown() throws Exception { // uninitialize test fixture variables. }

// test methods …}

Also refer to @BeforeClass and @AfterClass annotations.

Page 28: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

28

Examplepublic class PointTest { private Point p;

@Before public void setUp() { p = new Point(10, 10); } @Test

public void testSetX() { p.setX(20); assertEquals(20, p.getX()); assertEquals(10, p.getY()); } @Test

public void testSetY() { p.setY(30); assertEquals(30, p.getY()); assertEquals(10, p.getX()); }}

Q: What if @Before is omitted and p is initialized to new Point(10,10)?

Page 29: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

29

More on JUnit -- Test Suite

Definition A test suite is a set of test methods and other

test suites. Test Suite

Organize tests into a larger test set. Help with automation of testing.

Page 30: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

30

Example

import org.junit.runner.RunWith;import org.junit.runners.Suite;

@RunWith(Suite.class)@Suite.SuiteClasses({ PlaceTest.class, BattleshipTest.class, BattleFieldTest.class})public class AllTests {}

In Eclipse, - Select a source code folder - Right click (pop-up menu) - Select New > Other … > JUnit > Junit Test Suite

Page 31: 1 Unit Testing with JUnit CS 3331 JUnit website at  Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,

31

More on JUnit?

Refer to www.junit.org