An object-oriented program comprises a collection of objects that collaborate to solve some problem. The ways in which those objects collaborate determine what a program does and, consequently, the correctness of a program's execution. An instance of a trusted primitive class, for example, may contain no faults, but if the services of that instance are not used correctly by other program components, then the program contains faults. Thus, the correct collaboration or interaction of objects in a program is critical to the correctness of the program. Most classes have collaborators that is, the methods in the class interact with instances of other classes. In Chapter 5, we addressed finding faults within the implementation of an individual class that had no such interactions. In Chapter 7, we address interactions between the definition of a subclass and the definition of its superclass. In this chapter we will expand our scope and address testing classes that do have interactions with other classes. The interactions being tested are between objects at runtime for example, when one object is passed to another as a parameter or when an object maintains a reference to another object as part of its state. Interactions always involve unidirectional messaging. Some interactions involve bidirectional messaging between the objects. In this chapter we will assume that the interactions are sequential. In Chapter 8, we will consider more complex relationships such as concurrent interactions among distributed objects that use concurrent interactions. The focus of interaction testing is ensuring that messaging occurs correctly with objects whose classes have already been tested separately. Interaction testing can be performed with the interacting objects embedded in an application program or by interacting the objects in an environment provided by a separate test harness, such as a Tester class. We will examine both approaches in this chapter. First, we will present details about what object interactions are and how interactions are identified in a class interface. Then we will look at testing interactions outside the context of a particular application program. Finally, we will consider some of the difficult issues that arise in testing interactions within the context of an application program and how these issues can be addressed. |