(c) 2002 object mentor, inc.1 testing things that seem hard to test robert koss, ph. d....

25
(c) 2002 Object Mentor, Inc. 1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. [email protected] www.objectmentor.com

Upload: clare-montgomery

Post on 19-Dec-2015

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 1

Testing Things That Seem Hard To Test

Robert Koss, Ph. D.ObjectMentor, Inc.

[email protected]

Page 2: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 2

Introduction

• XP dictates that we test everything that can possibly break– Subjective

• accessors and mutators

• What if mutator does validation?

• How much logic is too much?

• What if class Foo is difficult to test?

FooTest Foo

Page 3: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 3

Sources of Difficulty

• Some objects appear to be difficult to test– Objects which depend upon other objects.

– GUI’s

– Databases

– Servlets / EJB’s

• What makes these things hard to test?– Not knowing what to test

– Source code dependencies

• Collaborating objects

Page 4: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 4

Knowing What to Test

• GUI– Assume Swing / MFC works

– Model-View-Controller

• Make sure anything that can break is in a class which can be tested

• Databases– Assume Oracle / SQL Server, etc. works

• Servlets– HttpUnit

– Delegate to a class which can be tested.

Page 5: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 5

Collaborating Objects

• Mark IV Coffee Maker

+makeCoffee()

CoffeeMaker

+ hasWater()

Boiler

+hasEmptyPot()

Warmer

+ testMakeCoffee()

CoffeeMakerTest

public void testMakeCoffee() {

CoffeeMaker cm = new CoffeeMaker();

cm.makeCoffee();

assert( ? ? ? );

}

Page 6: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 6

Breaking Troublesome Dependencies

• A source-code dependency can always be broken by the judicious use of an interface.

• Dependency has been inverted– Both A and B now depend upon an interface

• A no longer knows concrete type of B– Can now test A by supplying a MockB

A B A

B

<<interface>>

IB

Page 7: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 7

Mock Objects / Stubs

• Class A can’t tell if message goes to class B or class BStub

• Class BStub used to create testing environment, totally under control of class ATest

A

B

<<interface>>

IBATest

BStub<<creates>>

Page 8: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 8

Self-Shunt Pattern

• Not always necessary to make a new class and create a new object for Bstub

• Class ATest can implement the IB interface

A

B

<<interface>>

IBATest

Page 9: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 9

CoffeeMakerTest

• Stub out Warmer and Boiler

+makeCoffee()

CoffeeMaker

+ hasWater()

<<interface>>Boiler

+hasEmptyPot()

<<interface>>Warmer

+ testPotWater()+ testPotNoWater()+ testNoPotWater()+ testNoPotNoWater()

CoffeeMakerTest

MarkIVBoiler

Page 10: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 10

Stubs Everywhere ?

• Stubs are good when real class can’t easily be used– Hardware

– Database

– Dependent class not done

• Not necessary for Value Objects• Not necessary if dependants are known to work

Page 11: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 11

Chains of Dependencies

• Bowling Game

• Boom, Splash, (x, y, z, t)

Game Frame Throw10 1, 2, 3

Trigger

Page 12: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 12

More Uses for Stubs

• Logging– When object under test is supposed to send a sequence of

messages to another object in a specific order

– Record message sent as a string

• append to string for each message

– Alternative to setting several flags and examining in test

Page 13: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 13

More Uses for Stubs

• Null Object Pattern– When doing nothing is the right thing to do– Don’t have to test for presence of Logger object

ClassTestedA Lot

<<interface>>Logger

FileLoggerNullLogger

Page 14: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 14

Testing GUI’s• Test Model (MVC) first

– Concentrate on business instead of user interface

– Start just inside the UI

– Quicken

• addCheck( new Check( checkNum, payee, amount)) is more important than a fancy check gui

• Same with reconcile()

Page 15: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 15

Testing GUI’s

• Decide what to test– Can test everything except for aestetics

– Should we?

• http://users.vnet.net/wwake/xp/xp0001/

public void testWidgetsPresent() {

SearchPanel panel = new SearchPanel();

assertNotNull(panel.searchLabel);

assertNotNull(panel.queryField);

assertNotNull(panel.findButton);

assertNotNull(panel.resultTable);

}

Page 16: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 16

Being Pragmatic

• Assume GUI toolkit works– Swing, MFC, Qt, GTK

– new Button( “OK”);

• Continually ask if code being written can possibly break

• Continually ask if code being written is doing more than UI

• Make sure all logic is in classes that can be tested• Make GUI code so thin that it can’t possibly break.

Page 17: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 17

Separate Domain From User Interface

• Model - View - Controller• Document - View

– Combines traditional View with Controller

– Good unless several Controllers are needed

• Model - View - Presenter– http://www-106.ibm.com/developerworks/library/

mvp.html

– Combines traditional View with Controller

– Adds another layer between UI and Model

– Presenter is ideal place to do unit testing of GUI

Page 18: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 18

Single Responsibility Principle

• A class has a single responsibility. It meets that responsibility, the whole responsibility, and nothing but that responsibility– Called cohesion in Structured Design

• Applied to functions– Rule of thumb

• Describe class’s responsibility without using “and”

• What is the responsibility of an event handler?– “Handles” event– Scope of “handle” subjective– Should not have any program logic

Page 19: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 19

A Stupid GUI Is an Unbreakable GUI

• Event handler should do nothing but gather the information from event and delegate responsibility to another class– Can’t possibly break

– e.g., MouseEventHandler should get click coordinates and delegate to another class that knows what to do when the mouse is clicked

• hit testing

Page 20: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 20

Event Handlers

• Dialog / Window with GUI Control and registered listener

Control 1

<<interface>>Listener 1

SomeWindow

<<anonymous>>

• Testing listener can be– Easy / Annoying

– Hard / Impossible

How do we test this?

Page 21: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 21

Event Handlers Delegate

• Have event handler delegate to something that can be tested

Control 1

<<interface>>Listener 1

SomeWindow

<<anonymous>>

ModelFacade

<<delegates>>

ModelFacadeTest

Presenter (MVP)

Page 22: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 22

General Architecture

• Note the direction of the dependencies

UI

ModelFacade

Model

ModelFacade

TestModelTest

GUIToolkit

Make this unbreakable

Page 23: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 23

Interacting GUI Components

• Interaction with one GUI component causes changes to other components.– Menus becoming active / inactive

– Toolbar changes

• Mediator Pattern– Have each event handler delegate to mediator and have

mediator determine what else must change

– Component interactions now localized (and testable!) instead of being distributed over all event handlers.

Page 24: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 24

Mediators as State Machines

• Using a Mediator localizes inter-object communication

• Mediators can become ugly for complicated windows

• Implementing Mediator as a state machine makes it easy to get the wiring correct and to easily accommodate changes

Page 25: (c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc. koss@objectmentor.com

(c) 2002 Object Mentor, Inc. 25

Summary

• We have to test everything that can possibly break• If something appears hard to test, don’t let it do

anything that can break– Delegate to an object that can be tested