The terms “component” and “component-based software engineering” are relatively recent. Although there is broad agreement on the meaning of these terms, different authors have sometimes used slightly different interpretations. Following Brown and Wellnau [4], here we view a component as “a replaceable software unit with a set of contractually-specified interfaces and explicit context dependencies only.” A component is a program or a set of programs developed by one organization and deployed by one or more other organizations, possibly in different application domains. To date, many component systems are designed and developed using object technology. The same is true of middleware architectures that support the deployment of components, such as Java Beans [3], CORBA [1], and DCOM [5]. Although there is consensus that the issues in component-based software engineering cannot be solved merely by object technology [4, 14], these technologies will clearly play a fundamental role in the production of software components [15]. It is quite likely that developers will use with increasing frequency object technologies in the design and implementation of components. For this reason, in the sequel we focus on testing of components that consist of an object or a set of cooperating objects. In addition, we consider messages sent to a component as method invocations on the objects contained in the component.
Programs developed with object technologies have unique features that often make traditional testing techniques inadequate. An important feature of these programs is that the behavior of a method may depend on the state of the method receiver. Since the state of an object at a given time reflects the sequence of messages received by the object up to that time, erroneous behaviors may be revealed by exercising specific sequences of messages. Component testing should identify sequences of messages whose execution is likely to show the existence of faults; however, traditional unit and integration testing techniques do not produce this kind of information [2] Our method uses various kinds of structural analyses in order to produce sequences of method invocations for the component under test. A byproduct of these analyses is the definition of formal specifications in the form of preconditions and postconditions for the methods contained in the component under test. When performing integration testing, the method sequences resulting from the analysis of single components are then used jointly.