the design of junit yonglei tao. test-first development an essential element in extreme programming...

43
The Design of JUnit Yonglei Tao

Upload: esmond-morrison

Post on 11-Jan-2016

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Design of JUnit

Yonglei Tao

Page 2: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Test-First Development An essential element in eXtreme

Programming (XP) Test is written before the code

As an executable and standalone component Includes the input and checks the result

Can run with an automated support Developers need to understand the

interface and functionality of a component first

Page 3: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

JUnit A free framework for unit testing

Written by Kent Beck & Erich Gamma Helps the developer create and run

individual and groups of test cases Allows test cases to be self-checked Allows to run test cases when changes are

made

Page 4: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

An Example Classclass Money {    

private int amount;     private String currency;   

public Money(int amt, String cur) {         amount= amt;         currency= cur;    

}     public int amount() {

return amount; }public String currency() {

return currency; }public Money add(Money m) {    

return new Money(amount() + m.amount(), currency()); }public boolean equals(Money other) {    

return amount == other.amout && currency.equals(other.currency)); }

}

Page 5: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

A Test Casepublic class MoneyTest {    

@Testpublic void testConstructor() {    

Money m1= new Money(12, "USD");     Money m2= new Money(14, "USD");  

   assertTrue ( !m1.equals(null) );     assertEquals ( m1, m1 );     assertEquals ( m1, new Money(12, "USD") );     assertTrue ( !m1.equals(m2) );

}}

Page 6: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

More Test Code a little, test a little, code a little, test a little

@Testpublic void testAdd() {        

Money m1= new Money(12, "USD");          Money m2= new Money(14, "USD");  

               Money expected= new Money(26, "USD");        

Money result= m1.add(m2);            assertTrue ( expected.equals(result) );      

}

Page 7: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Design Issues for JUnit A tool for unit testing Need to run test methods written by individual

programmers Need to work with test classes involving

different test methods Need to work with individual test cases as well

as collections of test cases

Page 8: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Command Pattern Problem

Need to issue a request for an object without knowing anything about the operation being requested or the receiver of the request

Need to support undo, redo, and callback Solution

Encapsulate a request as an object Delegate its intended functionality to the

responsible object

Page 9: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Command Class Hierarchy

Command

+Execute()+Undo()

InsertLineDeleteLine

+Execute()+Undo()

-LineNo : int-DeletedLine : String

Replace

Page 10: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Participating Objects

Visual Control ViewInsertLineCom m and

Docum ent

OnInsertLineClick()

Excute()

InsertLine()

Create()

ntClient

Page 11: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Consequences Extend class Command for each of the

commands Let it be responsible for executing itself Let it keep info needed for undoing/redoing

Support undoable operations as well as to queue or log users’ requests Also callback

Adding or removing a command doesn't affect the client code

Page 12: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Template Method Pattern Problem

How to defer decision on details of an algorithm How to allow a step in an algorithm to vary

Solution Let a method in a superclass defines the

skeleton of an algorithm with its varying and unvarying parts

Let subclasses override the varying parts in order to add their specific behavior at points of variability

Page 13: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

An Example of the Template Method

Page 14: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

An Example (Cont.)public class Account {

public void Transaction() { A(); B(); C(); }public void A() { … }public void B() { … }public void C() { … }…

}

public class SavingsAccount extends Account {

public void C() { … } …

}

public class JuniorAccount extends Account {

public void A() { … }…

}

Page 15: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Applicability The template method should be used

To implement the invariant parts of an algorithm once and let subclasses implement behavior that can vary

When common behavior among subclasses should be factored and localized in a common class to avoid code duplication

To control subclass extension The template method defines hook operations Subclasses can only extend these hook

operations

Page 16: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

View

+update()+repaint()

MyView

+repaint()

// template methodvoid update () { clearBackground(); repaint(); ......}

// hook methodvoid repaint () { // draw string or graphics}

Use of the Pattern in C++, Java, …

Page 17: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Consequences Most commonly used An important pattern for framework and

class library design Inverted control structure

Parent class calls subclass methods Important to denote which methods

Must overridden Can / Can not be overridden

Page 18: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Adapter Pattern Problem

How to resolve incompatible interfaces or provide a stable interface to similar components with different interfaces

Solution Convert the original interface of a component

into another interface, through an intermediate adapter object

Also known as Wrapper

Page 19: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Structure

Page 20: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Composite Pattern Problem

How to allow clients to treat individual objects and compositions of objects uniformly

Solution Organize objects into a tree structure that

represents an aggregation hierarchy

Page 21: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Client

«Interface»Component

+operation() : void+addCom ponent() : void+rem oveCom ponent() : void+getChild(n : int) : Com ponent

Composite

+operation() : void+addCom ponent() : void+rem oveCom ponent() : void+getChild(n : int) : Com ponent

Leaf

+operation() : void

Structure

Page 22: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

GUI Windows and Elements

How does the window hold and deal with the different items it has to manage?

Page 23: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Using the Composite Pattern

Page 24: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

// Component implements default behavior for widgets when // Button, Menu, TextArea, and WidgetContainer override// Component methods as needed

class WidgetContainer { Component[] myComponents;

public void update() { if ( myComponents != null )

for ( int k = 0; k < myComponents.length(); k++ )

myComponents[k].update(); } }

Composite (Cont.)

Page 25: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Consequences Make the client simple Make it easy to add new kind of

components and remove existing ones Make the design general and reusable Using the pattern when

To represent part-whole hierarchies of objects Clients to be able to ignore the difference

between compositions of objects and individual objects

Page 26: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Design of JUnit Serve as a framework within which

developers can write and run tests Easy to learn and to use

Create tests that can be performed as needed Someone other than the original author has to

be able to execute the tests and interpret the results

Creating test cases is expensive and the framework has to enable reusing them

Page 27: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

1. Getting Started How to run test cases that are written by

individual programmers? Allow to run tests in a graphical user interface

or on the command-line Make manipulating tests easy

Page 28: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Command Pattern Separating a request for executing a

command from its execution User interaction object vs. domain object

Allowing to invoke different implementations of a command through the same interface

Page 29: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Pattern Implementation

public abstract class TestCase implements Test {     private final String fName;    

public TestCase(String name) {         fName= name;     }

    public abstract void run();

…}

Page 30: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

2. Defining Tests How to give the programmer a convenient

“place” to put their test code? Need a common structure to all tests

Set up test data, run some code against the data, check results, and then clean up the data

Page 31: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Template Method Pattern Define the skeleton of an algorithm in an

operation, deferring some steps to subclasses Let subclasses redefine certain steps of an

algorithm without changing the algorithms’ structure

Allow the programmer to consider how to write the test code without worrying about how to run it Execution of this sequence remains the same for

all tests, no matter how the testing code is written

Page 32: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Pattern Implementationpublic class TestCase implements Test {

private final String fName;     public TestCase(String name) {         fName= name; } public void run() {     setUp();     runTest();     tearDown(); }protected void runTest() { } protected void setUp() { } protected void tearDown() { }

}

Page 33: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

3. Reporting Results How to collect test results? Need to capture what did and did not work

after the test has run Tests usually work – only need to record the

failure and a highly condensed summary of the successes

Page 34: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Collecting Parameter Pattern Add a parameter to the method and pass

an object that will collect the results from that method

JUnit distinguishes between failures and errors Failures are anticipated and checked for with

assertions Errors are unanticipated problems

Page 35: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Pattern Implementation

public void run (TestResult result) {     result.startTest(this);     setUp();     try {         runTest();     }     catch (AssertionFailedError e) { // capture failures         result.addFailure(this, e);     } catch (Throwable e) { // capture errors        result.addError(this, e);     }     finally {         tearDown();     } }

Page 36: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Class TestResultpublic class TestResult extends Object {

protected int fRunTests;     protected Vector fErrors, fFailures;public TestResult() {     fRunTests= 0; fErrors = new Vector(); fFailures = new Vector();} public synchronized vid startTest (Test test) { fRunTests++;}public synchronized void addError(Test test, Throwable t) {     fErrors.addElement(new TestFailure(test, t)); } public synchronized void addFailure(Test test, Throwable t) {     fFailures.addElement(new TestFailure(test, t)); }

}

Page 37: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

4. Handling Different Test Cases How to run test cases that are

implemented as different methods in the same class? A test case class may implement many

different methods, each defining one test case such as testMoneyEquals or testMoneyAdd

Need to make all test cases look the same from the point of view of the invoker of the test

Page 38: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Adapter Pattern Converting the interface of a class into

another interface that clients expect Using a class adapter requires to implement a

subclass for each test case – too much burden on the tester

So use pluggable selector as default implementation of method runTest() in an anonymous adapter class

Page 39: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Pattern Implementation

protected void runTest() throws Throwable {     Method runMethod= null;     try {         runMethod= getClass().getMethod(fName, new Class[0]);     } catch (NoSuchMethodException e) {         assertTrue("Method \""+fName+"\" not found", false);     }     try {         runMethod.invoke(this, new Class[0]);     }     // catch InvocationTargetException & IllegalAccessException

}

Page 40: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

5. Dealing with One and Many How to run a single test case and report its

result in a TestResult as well as run a group of test cases and report their results?

Need to support suits of suits of suits of tests

Page 41: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

The Composite Pattern Allowing clients treat individual objects and

groups of objects uniformly

Page 42: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Class TestSuite

public class TestSuite implements Test {

private Vector fTests= new Vector();

public void run(TestResult result) { // delegates to its children    for (Enumeration e= fTests.elements(); e.hasMoreElements(); ) {         Test test = (Test) e.nextElement();         test.run(result);     } }

public void addTest(Test test) {     fTests.addElement(test); }

}

Page 43: The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable

Summary