29.11.2014 Views

Smalltalk and Object Orientation: an Introduction - Free

Smalltalk and Object Orientation: an Introduction - Free

Smalltalk and Object Orientation: an Introduction - Free

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

22. Testing <strong>Object</strong> Oriented Systems<br />

22.1 <strong>Introduction</strong><br />

Testing object oriented systems is a very import<strong>an</strong>t issue as more <strong><strong>an</strong>d</strong> more org<strong>an</strong>izations are starting to<br />

develop <strong>Smalltalk</strong> (as well as C++ <strong><strong>an</strong>d</strong> Java ) based applications. M<strong>an</strong>y such org<strong>an</strong>izations have been<br />

forced to come up with their ow n solutions for assuring the quality of their product. However, little<br />

attention has been focused onto this subject at <strong>Smalltalk</strong> -centered conferences or in <strong>Smalltalk</strong> literature<br />

(see the workshop at OOPSLA-95 for a notable exception). There is a particular scarcity of literature on<br />

“how-to” test <strong>Smalltalk</strong> systems as well as tools to support such testing. For org<strong>an</strong>izations just starting<br />

to use <strong>Smalltalk</strong> for major projects this is a very worrying situation.<br />

<strong>Object</strong> oriented techniques do not (<strong><strong>an</strong>d</strong> c<strong>an</strong>not) guar<strong>an</strong> tee correct programs. They may well help to<br />

produce a better system architecture <strong><strong>an</strong>d</strong> <strong>an</strong> object oriented l<strong>an</strong>guage may promote a suitable coding<br />

style, but these features do not stop a programmer making mistakes. Although this should be self<br />

evident, for a l ong time there was a feeling that object oriented systems required less testing th<strong>an</strong><br />

systems constructed with traditional procedural l<strong>an</strong>guages, was prevalent (for example see the book<br />

describing the OMT method by Rumbaugh et al).<br />

Where the testing of object oriented systems has been considered it is often the user interface of the<br />

system which has actually been tested in a principled or systematic m<strong>an</strong>ner. These tests usually<br />

concentrate on overall system functionality, u sability issues (such as the ability of the user to use the<br />

system or the speed of response) <strong><strong>an</strong>d</strong> stress or exception testing. Stress or exception testing relate to<br />

attempting to break the operation of the system by inputting unacceptable data or crashing p art of the<br />

system (e.g. <strong>an</strong> associated relational database system) to ensure that the system c<strong>an</strong> recover from such<br />

catastrophic failures.<br />

However, this chapter aims to show you that if <strong>an</strong>ything, object oriented systems require more<br />

testing, not less testin g th<strong>an</strong> traditional programming l<strong>an</strong>guages. In the remainder of this chapter we<br />

shall consider what effects inherit<strong>an</strong>ce, encapsulation, polymorphism <strong><strong>an</strong>d</strong> dynamic typing have on<br />

testing as well as approaches to method <strong><strong>an</strong>d</strong> class (unit) testing, object integration <strong><strong>an</strong>d</strong> system testing.<br />

22.2 Why is testing object oriented systems hard?<br />

22.2.1 An example<br />

To illustrate the point consider the following <strong>Smalltalk</strong>. Let us assume that we have defined a method<br />

returnSymbol which returns a symbol based on the current state of <strong>an</strong> object . Let us also assume<br />

that we have defined <strong>an</strong>other method passesTheTest which returns true or false based on the state<br />

of its object. We could then write the following method:<br />

myMethod: aCollection <strong><strong>an</strong>d</strong>: <strong>an</strong><strong>Object</strong><br />

| aVariable |<br />

aVariable := <strong>an</strong><strong>Object</strong> returnSymbol.<br />

aCollection do: [:item | (item passesTheTest) ifTrue:<br />

[item perform: aVariable]].<br />

In this case it is very difficult to determine statically what is going to happen in this method. This is<br />

because until the method is executed, we do not k now the content (let alone the type (class) of the<br />

objects) in aCollection. We c<strong>an</strong>not determine therefore which objects must respond to the<br />

passesTheTest message. Nor c<strong>an</strong> we determine which objects will return true from this message<br />

<strong><strong>an</strong>d</strong> thus which objects will cause the ifTrue block to be evaluated. In this example, the situation is

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!