Goel-object_oriented_software_testing

					Object Oriented Software Testing: A Survey Report
Anita Goel Sr. Lecturer, Dyal Singh College, University of Delhi, Lodi Road, New Delhi-3 Dr. S.C. Gupta Senior Technical Director, NIC, A Block, CGO Complex, New Delhi-3 Prof. S.K. Wasan Professor, Department of Mathematics, Jamia Millia Islamia, New Delhi-25

Abstract: Software testing techniques have evolved over the years and in order to handle the unique testing issues of the object oriented software, the conventional software testing techniques need to be adapted and new ones need to be developed. The unique architecture and features like inheritance and polymorphism introduce new kind of errors in the object oriented software. As a result, some of the issues involved in the testing of the object-oriented software are different from the testing issues of the conventional software. Class is the focus of unit testing in object oriented software. Resolution of relationships at runtime due to dynamic binding complicates testing. Moreover, the paradigm shift from the waterfall model of software development to the iterative and incremental style of software development has resulted in object oriented software testing being iterative and incremental in nature. This paper highlights the issues unique to the testing of object oriented software. Also included, is a description of the testing process and survey of the different testing techniques and tools developed to test the object-oriented software at the unit, integration and system level.

1. Introduction
The object oriented approach to software development does not rule out the need to test the software. Object oriented software needs to be tested, though, as a result of the different architecture and unique features of the object oriented software some of the testing issues of object oriented software are different from the testing issues of the conventional software. The unique testing issues of the object oriented software necessitate improvisation of the conventional software testing techniques and development of new testing techniques. Class is the basic unit of testing in object oriented software. Class is a complete unit that can be isolated and tested independently. The inheritance feature of the object oriented approach allows a new class to be derived from an existing class. The inherited methods need to be retested in the derived class in context of their usage in the derived class. Dynamic binding, another powerful feature of the object oriented approach binds the relevant method at runtime. Late binding creates indefiniteness in the testing process since the method to be executed is unknown until runtime. As opposed to the waterfall model used for traditional software development, object oriented software is

1

2

developed using the iterative and incremental approach. Thus, object oriented testing too becomes iterative and incremental, requiring use of regression testing techniques. Object oriented software is tested at the unit, integration and the system level. At unit level, class is the basic unit of testing. Different approaches like the state-based testing and data-flow testing use the black-box, white-box and gray-box testing techniques to test the class. The already tested classes interact with each other via relationships like inheritance and aggregation to form a subsystem. Integration testing tests for interface errors in the interacting units of the subsystem. System testing tests the complete application software. Object oriented software testing is aided by testing tools. The testing tools automate the test case design and execution, and the result evaluation at different stages of testing. The paper is divided in different sections. In section 2 we discuss in brief the features of the object oriented software. Section 3 deals with the testing issues unique to the object oriented software. Section 4 discusses the testing process used to test the object oriented software at the three levels of testing- unit, integration and system level. It includes a survey of the testing strategies used in the testing of the object oriented software. Section 5 describes briefly the testing tools developed to test the object oriented software.

2. Object Oriented Software
Class is the basic building block in object oriented software. A class is a template for a set of objects that share a common data structure and common behavior. The data structure and the behavior of the class are represented by the data and the methods defined in the class respectively. Objects are instances of the class. An object has a state, defined behavior and a unique identity. The state of the object is represented by the data defined in the object. Encapsulation, inheritance and polymorphism are features unique to object oriented software. Encapsulation hides the implementation details of the class. The class encapsulates the data and the internal methods. The interaction with the class is through the set of methods that provide an interface for the class. Inheritance allows a new class (derived class) to be derived from an already existing class (base class). The derived class inherits all the features of the base class (data and methods), may override some features of the base class or

2

define its own set of data and methods. Polymorphism allows different objects to respond to the same message in different ways. It is implemented by static or dynamic binding. Static binding occurs at compile time by the overloading of the operator or method name to provide different functionality. Dynamic binding binds the function call to the relevant method at run time. The method to be executed is unknown until runtime. Inheritance facilitates reusability of the class by extending functionality of existing classes to suit new requirements.

3. Testing Issues
The architecture of the object oriented software differs from the conventional software architecture. Features like encapsulation, inheritance, polymorphism and reusability are unique to object oriented software. Thereby, some issues involved in the testing of the object oriented software are different from the testing issues of the conventional software. These testing issues are discussed in detail in following subsections.

3.1.

Class-Basic unit of testing

A unit that can be isolated and tested independently, is a suitable candidate for unit testing. In conventional software, module is the basic unit of testing. It can be isolated and tested as an independent unit. The data may be defined within the module or may be globally declared. In object oriented software, class is the basic unit of testing. The class as a standalone component, is a complete unit and can be tested independently. The class encapsulates the data and has methods that operate on the data defined in the class. Since method of the class manipulate the data defined in the class, methods cannot be isolated from the class to form a standalone unit. Moreover, objects have state and exhibit state-dependent behavior. The state of the object is represented by the data associated with the object. Execution of the method depends on the state of the object at the time of method invocation. Execution of the method may also alter the state of the object. Therefore, testing of the method requires observing the impact of method execution on the state of the object. The method thus cannot be isolated from the class for the purpose of testing. Furthermore, the methods of the class are invoked via an instance of the class. The class needs to be instantiated to facilitate access to the methods of the class.

3

4

There is a general consensus on class as the basic unit of testing. [BS94][Ber94][MTW94][TX96] [GGS97] give arguments in support of class as the basic unit of testing.

3.2.

Inheritance

Inheritance allows a new class called subclass, to be derived from an already existing class called the superclass. In conventional software, module once tested is seldom tested again. In contrast, inheritance hierarchy requires retesting of the superclass in context of its usage in the subclass. Creation or modification of an inheritance hierarchy can take place in any of the following ways(a) Modification of the superclass. (b) Creation/Modification of the subclass - Overriding methods of the superclass (c) Modification of the superclass data structure from the subclass. (d) Creation/Modification of subclass-Pure extension of the superclass. These different kind of modifications result in several issues in the testing of the inheritance hierarchy. (a) Modification of the superclass

The superclass in an inheritance hierarchy is an already tested class. Any modification of the superclass necessitates retesting of the superclass along with all the classes dependent on it. It includes retesting of the subclasses that inherit the methods of the superclass. The amount of retesting required depends on the units affected by the modification of the superclass. According to [PK90], the Weyuker’s anticomposition axiom states that there is a necessity of retesting every unit dependent on a modified unit because a program that has been adequately tested in isolation may not be adequately tested in combination. (b) Creation/Modification of the subclass - Overriding Methods of the superclass

The subclass can have new, overriding or inherited data structure and methods. The NEW and the OVERRIDING data and methods defined in the subclass are the new members of the subclass. The overriding method in the subclass either implements a different functionality or is a new implementation of the overridden method of the superclass. Since both new and the overriding methods are new members of the subclass defined locally, they need to be tested completely in the

4

subclass. The interaction of the new and the overriding methods with the other methods of the subclass is tested next. In figure 1, the member function A in R is a new member function in R since the arguments of A in R are different from the arguments of A in P and the member function C of R is an overriding member function. New test set needs to be developed to test these methods. According to [PK90], the Weyuker’s antiextensionality axiom states that an existing test set of the overridden superclass is not adequate to retest the overriding subclass since their implementation and even the functionality may be different.

class P{ private: int i; int j; public: P(){} void A(int a, int b) {i=a; j=a+2*b;} int C() {return j;} int D(int j) {if j<=5 return j else return j+1;

class R: public P{ private: float i; public:

//new

R() {} void A(float a) //new {i=a+4.5;} int C() //overriding {return 2*P::C();} }; //D() is inherited

}; Figure 1. Class R is a subclass derived from class P (from [HMF92]) The INHERITED methods in the subclass are the methods that are declared and defined in the superclass and are inherited by the subclass. Since these methods are defined in the superclass they have already been tested in the superclass. However, the inherited methods in the subclass need to be retested in context of the subclass, since inherited methods are now being used in a different context in the subclass. For a method defined in the superclass, the part of the code that gets executed in the superclass may be different from the part of the code that gets executed when the same method is inherited and used in the subclass. In Figure 1 the method D is an inherited method in R. Even though the implementation of D has not changed in R the sequential execution of C(); D() may have a different impact in class P and in class R since the function C is different in the two classes. This necessitates retesting of D in context of class R. According to [PK90], Weyuker’s antidecomposition axiom states that when we add a new subclass or modify an existing subclass, we must retest the

5

6

methods inherited from each of its ancestor superclasses. The use of subclass adds this form of dependency because it provides a new context for the inherited components. Execution of D() in the subclass may execute that part defined in D() which may not have been adequately tested in context of its use in the superclass. (c) Modification of the superclass data structure from the subclass

In this case of inheritance, access is allowed to the data members of the superclass from the subclass. The data members of the superclass are declared as protected. The protected members of the class are not directly accessible from outside the class but are directly accessible from the subclass derived from it. The access to the protected members from the subclass breaks the wall of encapsulation. The superclass can thus be modified from the subclass. Therefore, superclass and all units dependent on the superclass need to be retested. (d) Creation/Modification of subclass-Pure extension of the superclass

The subclass in an inheritance hierarchy may be a pure extension of the superclass i.e. there is no interaction between the superclass and the subclass in either direction. In such cases, it appears that retesting of the inherited methods of the superclass is not required. [BER94] says that when the subclass inherits the tested method of the superclass there is no guarantee of the appropriateness of the same method within the context of the subclass. The method has to be retested within the context of the subclass. In a new context of usage, different paths may be followed and new faults may emerge. [BS94] discusses issues related to inheritance testing. [WEYU98] gives the example of the Ariane 5 launch vehicle that failed because of insufficiently tested software reused from the Ariane 4 launcher. A reuse specification error caused the failure.

3.3.

Polymorphism

Polymorphism means many forms i.e. allowing a single interface to more than one method. It is implemented using the same interface name for more than one method. The binding to the correct method may be static or dynamic. Static binding happens at compile time and dynamic binding occurs at runtime. Dynamic binding is the binding of the function call to the relevant method at runtime. Dynamic

6

binding is a powerful feature that allows the relevant method to be executed depending on the function call. The method to be executed is not known until runtime. This necessitates testing for the actual method that gets bound to the function call. Testing for the method that gets executed in response to a method call becomes complicated due to non-determination of the method to be executed until run-time.

Class shape { private: point a; public : shape(); virtual void draw(); virtual void area(); }; class circle : public shape { private: int radius; public : circle(); void draw(); void area(); }; class ellipse : public circle { private: int y_radius; public : ellipse(); void draw(); void area(); };

void main(void) { shape *s[10]; int ctr; obj_type //obj_type=1 if circle and 2 if ellipse for (ctr=0;ctr<10;ctr++) cin>>obj_type; switch(obj_type) { case 1: s[ctr] = new circle; //create instance of circle break; case 2: s[ctr] = new ellipse; //create instance of ellipse break; }; s[ctr]->draw(); // (1) s[ctr]->area(); //(2) };

Figure 2. Inheritance hierarchy implementing dynamic binding (only relevant part shown) Dynamic binding is implemented using the inheritance hierarchy. Figure 2 gives an example that implements dynamic binding. Draw and area are the methods that get dynamically bound to the function call depending on the type of object with which the base class, shape is invoked. If obj_type is 1 then an object of class circle gets created and statement (1) and (2) invokes draw and area of circle. If obj_type is 2 then an object of class ellipse is created and statement (1) and (2) invokes draw and area of ellipse. The relationships thus get identified at runtime necessitating testing of the binding of the correct method to the call. [AO98] describes coupling based technique for analyzing and testing polymorphic relationships in object oriented software. For any call to a method, all the methods and the relevant state variables that can satisfy the call are identified. It results in the set of definitions and uses of each satisfying method.

7

8

According to [Mari95], it is hard to tell the exact code that will be executed. It may be a method belonging to one of the many classes. For a single call, one needs to explore the union of all distinct behaviors.

3.4.

Incremental development

The object oriented software is developed using the iterative and incremental approach in contrast to the waterfall approach used to develop the traditional software. In the waterfall approach to software development, the different phases of the development cycle are executed sequentially. In contrast, the software is developed iteratively and incrementally, in the iterative and incremental approach to software development. In object oriented software developed using the iterative and incremental approach, the previous release results and experience are applied to the next iteration resulting in the successive refinement of the object oriented architecture. Each pass through the development cycle gradually converges to the solution that meets the user requirements resulting in the incremental development of the object oriented software. Testing being a phase of the development cycle, too becomes iterative and incremental. The iterative and incremental approach to object oriented software development helps in locating the fault early in the development cycle. Early detection and removal of errors prevents errors to get embedded in the software. This further helps to reduce the cost of rectifying the error since the rectification cost decreases with the reduction in the time between its injection and detection. The iterative and incremental development cycle results in many more changes to be made to the implemented and re-implemented classes in every iteration and increment. The change impact of the increment on the existing software needs to be identified to determine the amount of retesting required for the existing part of the software. Also, the test case development and execution needs to be flexible enough to incorporate the modifications in the testing requirements, as a result of the changes made to the software in each iteration and increment. Regression testing techniques become more relevant to the testing of the object oriented software developed using iterative and incremental approach. According to [Win98], in the waterfall software development process, integration testing is done

8

during development, to find errors in the interacting units and regression testing is done during the maintenance phase to test that the software continues to function properly after the modifications have been made to the software. However, in object oriented software, the iterative and incremental approach blurs this distinction and requires regression testing to be done along with integration testing to identify the impact of modification in each iteration and increment. [McK94] presents a testing strategy closely related to the iterative incremental development process model. The test cases at each stage of development are built incrementally from the already developed test cases.

4. Testing Process
The testing of object oriented software is done at three levels- unit level, integration level and system level. At unit level, the class is the unit of testing. Classes are integrated based on relationships like inheritance and aggregation to form a larger unit. Integration testing detects errors in the integrated units. System testing involves testing of the complete software.

4.1.

Unit testing

Class is the basic unit of testing in object oriented software. Testing of the class involves testing of the methods defined in the class and their impact on the state of the class/objects. Different approaches are used to test the methods of the class. Also, the state of the class/objects needs to be observed both before and after method execution. In object oriented software, an application is implemented by invoking methods in an order that implements its functionality. The methods of the class tend to be less complex and small in size, though large methods may also exist. In traditional software the modules are generally large in size and require statement-level testing techniques to test the module. So the testing techniques that are effective to test a module in traditional software may not prove to be that effective for the testing of the method in object oriented software. However for large methods, the testing techniques of the conventional software like white-box testing can be used to perform statement-level testing of the methods. White-box testing is based on the close examination of the procedural details of the unit. It tests the statements, branches, control flow and data flow of the source code without any reference to the specification. Coverage criteria are applied to determine the code coverage of the unit. Basis path

9

10

testing (Flow-graph, Mccabe’s cyclomatic complexity, graph matrices) and control structure testing (Condition testing, data flow testing, loop testing) are some of the white-box testing methods. The class can be tested as a single unit, without going into statement-level details of the methods, using black-box testing techniques. Black-box testing determines whether the program meets its functional and non-functional requirements without regard to its implementation. It also tests the effect of method called, on the state of the object. Functional test cases are constructed based on the specification of the unit. Coverage methods are used to determine the percentage of the class specification that is covered in testing. Boundary value analysis, equivalence class partitioning, graphbased testing are some of the black-box testing methods. Only white-box testing or only black-box testing is not sufficient for unit testing of object oriented software. White-box testing tests whether the code that exists works properly but does not test for forgotten code or functionality. On the other hand, black-box testing tests whether the unit works according to the specification but does not assure whether testing of all parts of the code has been exercised. A much better and efficient way to test the class is to use a combination of the black-box and white-box testing techniques. This is also called gray-box testing. Gray-box testing is based on both the examination of the specification of the software and the underlying implementation for the same. [Bois97][MTW94][JKNZ94][PK90] suggest using combination of both white-box and black-box testing techniques for testing the class. [CHE98] describes an integrated approach using black-box and white-box testing techniques to test a class. The black-box testing technique is used to select test cases. The white-box testing technique is applied to determine the observational equivalence of objects resulting from program execution of a test case. [JKNZ94] gives steps to test a method or interworking of methods- instantiate an object, set to proper state, set parameters, call method, check state of the called object and check state of all parameters. [BS94][JKNZ94a] discuss the problems in the testing of abstract and template classes. [KIM95] suggest the use of state charts and object state diagrams for testing of a class. [TX96][Bind96][TR95][McG94] give state-based testing approaches to test a class. [TX96] uses predicate/transition net to transform class specification and implementation into object test mode (OTM). A test tree is generated, based on OTM, state space

10

partition of the class and test data set for each method of the class. Test cases are derived from the test tree and the results verified. [Bind96] defines FREE (Flattened Regular Expression) approach for complete representation-based test suite for object oriented software. Test sequences are generated to cover all state transition cycles for the class. [TR95] discusses a new technique based upon the modeling of classes as finite state automata and using automata to generate test cases. [McG94] describes a functional testing approach to test a class. An algorithm is given for constructing test cases from the state representation of the specification of the class. [HR94] supports data flow testing of the class. It focuses on applying data flow testing techniques when users of the class invoke methods in an arbitrary order. The def-use pairs are identified and a class-control graph is constructed. Existing inter-procedural analysis algorithm is applied to the graph to determine the sequences to be executed to test the class.

4.2.

Integration testing

A system is divided into subsystems with the purpose of supporting distributed and parallel development of the subsystems [IEEE]. A subsystem is a logical collection of classes that interact with each other in a way that implements the functionality of the subsystem. The subsystem has a well-defined interface through which the services of the system can be invoked and used. Integration testing tests for errors in the interacting units of the subsystem. Subsystem in an object oriented software is a grouping of classes related with each other via relationships like inheritance, aggregation and dynamic binding. The interacting units of the subsystem in an object oriented software connected via different relationships integrate to form a unit again. The subsystem in object oriented software is thus viewed as a large integrated unit composed of other class units or integrated units. The subsystem thus developed has a unique architecture, different from that of conventional software. Due to the lack of hierarchical control structure, strictly top-down and bottom-up integration strategies are less meaningful for object oriented software. New errors emerge when already tested units are integrated via different relationships. Integration testing of units related via different relationships test for proper sequence of method invocation and correct updating of states for implementing a single functionality. Classes related via inheritance

11

12

require retesting of the inherited methods, in context of their usage in the subclass. Integration testing of dynamic binding implementation tests for the binding of the relevant method at runtime. Since the iterative and incremental approach to object oriented software development results in incremental development of the software, the subsystems in the object oriented software are developed and tested incrementally. [LFWD2k] defines a test order that minimizes the number of stubs to be constructed in the integration of units. It takes into consideration the dynamic dependencies and the abstract classes. [Win98] draws a class message diagram (CMD) and uses it to identify the change impact and defines an algorithm and coverage criterion for integration and regression test strategies. [JE94] proposes a two-level strategy for integration testing of an ATM system. First the MM (method-message) path is tested, followed by testing their interaction in an Atomic System Function (ASF). MM-path starts with a method and ends when it reaches a method that does not issue any message of its own. An ASF starts with an input port event, followed by a set of MM-paths and terminated by an output port event. [MTW94] developed an ACE (Automated class exerciser) tool to automate class and cluster tests. It is based on the functional dynamic testing of the application specific clusters. Cluster test cases consists of the test plan, test cases and recording of the results. ACE also helps in the regression testing of the clusters in case of an implementation change. [JKZ94] gives an overview of integration testing strategy. He suggests integration testing of a single class, class hierarchies/libraries and of application programs. According to him integration testing of application programs is difficult because of inheritance, call/use relations and aggregation. According to [Bind95], there are two basic strategies of integration testing-thread-based and uses-based. A thread consists of all the classes needed to respond to a single external input. Uses-based integration starts by testing classes that use no or few server classes followed by next group of classes and so on. [HMF92] gives an incremental testing technique to assist in the testing of subclasses in an inheritance hierarchy. The subclass is tested by incrementally updating the history of the parent class to reflect the differences from the parent.

4.3.

System Testing

A system is a collection of subsystems organized to accomplish a specific function or a set of

12

functions (IEEE). In system testing the complete application software is tested. It tests whether the complete software works in accordance to the user specification. System testing is done in terms of the input and output boundaries that are visible at the user interface level of the system. System testing is performed on the target platform. System testing of object oriented software is similar to system testing of the conventional software [JKNZ94]. Thus the system testing techniques of the conventional software are applicable to the system testing of object oriented software. Conventional black-box testing techniques can be applied to perform system testing of an object oriented software. The programming paradigm does not change the user interface or the functionality of the complete program.

5. Testing Tools
Testing software using any testing strategy must incorporate test planning, test case design, test execution and resultant data collection and evaluation. Preparation, execution and analysis of thousands of test cases and the test data are manually unmanageable. Effective testing requires automation of the testing process. Extensive tool support is needed for the preparation and execution of the test cases and the verification of the result. [KIM95] developed a tool support to understand the system to perform regression and maintenance testing of the object oriented software. [DF94] describes a test generation and execution tool ASTOOT. It allows substantial automation of unit testing of object oriented programs. ASTOOT consists of a tool that automatically generates test drivers from class interface specifications and a tool which semi-automatically generates test cases from an algebraic specification of the class under test. The test drivers automatically execute and check the results. [KR98] describes a tool developed to test object oriented software that eliminates the need to write special-purpose test code. The tool allows interactive creation of instances of classes and interactively invocation of their methods. The internal state variables of the object can also be examined. [DHS2k] discusses the Roast tool and techniques for Java class testing. Roast generates test drivers from test scripts with embedded test cases. It also provides for automated class testing and support for generating boundary values and combinations of boundary values.

13

14

6. Summary
• The unique architecture and features of the object oriented software results in several testing issues that are different from the testing issues in conventional software. • • • Class is the basic unit of testing in object oriented software. Inheritance hierarchy requires retesting of the inherited methods in context of the subclasses. Due to dynamic binding, the method called is known only at runtime, which introduces indefiniteness in the testing process. • The iterative and incremental approach in object oriented software development results in iterative and incremental testing. • In integration testing units related via relationships like inheritance, dynamic binding, aggregation and association are tested. • • System testing of object oriented software is same as conventional software system testing. Object oriented testing tool aid in the creation and execution of test cases, and verification of results. Bibliography [AO98] R.T. Alexander, A.J. Offutt, "Analysis Techniques For Testing Polymorphic Relationships", 1998. [Ber94] Ed Berard, "Issues In The Testing Of Object-Oriented Software," Electro/94 International, Conference Proceedings Combined Volumes. IEEE Computer Society Press, Los Alamitos, California, pg 211-219, 1994. [Bind95] Robert V. Binder, "Testing Object Oriented Systems: A Status Report", CrossTalk, April 1995. [Bind96] Robert V. Binder, "The FREE Approach For System Testing Use Cases Threads And Relations", Object Magazine, Feb 1996. [Bois97] Jean Boisvert, "OO Testing In The Ericsson Pilot Project", Object magazine, July 1997. [BS94] S. Barbey, A. Strohmeier, "The Problematics Of Testing Object Oriented Software", In SQM '94 Second conference on software quality management, Edinburg, Scotland, UK, vol 2, pg 411-426, July 1994. [CHE98] H.Y Chen, T.H Tse, F.T. Chan, T.Y. Chen, "In Black And White: An Integrated Approach To Class level Testing Of Object Oriented Programs", ACM Trans. Of

14

Software Engineering And Methodology, Vol. 7, No. 3, 250-295, July 1998. [DF94] R.K. Doong, P.G. Frankl, "The ASTOOT Approach To Testing Object-Oriented Programs", ACM Transactions on Software Engineering and Methodology, April 1994. [DHS2k] N. Daley, D. Hoffman, P. Strooper, "Unit Operations for Automated Class Testing", March 2000. [GGS97] A. Goel, S.C. Gupta, K.D.Sharma, “Object Oriented Testing: An Overview” ,In Proceedings of the International Conference on Software Engineering And Its Application, Hyderabad, India, Dec 1997. [HMF92] M.J. Harrold, J.D. McGregor, and K.J. Fitzpatrick, “Incremental Testing Of ObjectOriented Class Structures”, In 14th International Conference on Software Engineering, ACM Inc., 1992. [HR94] M.J. Harrold and G. Rothermel, " Performing Data Flow Testing On Classes", In Second ACM SIGSOFT Symposium on Foundations of Software Engineering, ACM Inc., 1994. [JE94] [JKZ94] P.C. Jorgenson, C. Erickson, "OO Integration Testing", Comm. of ACM, Sept 1994. P. Juttner, S. Kolb, P. Zimmerer, "Integration And Testing Of Object-Oriented Software", EuroSTAR, pages 71-101, Jackson, FL., Oct. 1994. [JKNZ94a] P. Juttner, S. Kolb, U. Naumann, and P. Zimmerer, "A Complete Test Process In Object-Oriented Software Development", In 7th Annual Software Quality Week, San Francisco, CA., May 1994. [KIM95] Chen, Kim, "Developing An Object Oriented Software Testing And Maintenance Environment", Comm. of ACM, Oct 1995. [KR98] Kolling, Rosenberg, “Support For Object Oriented Testing”, In Technology of OO languages, TOOLS 28 Proceedings, pg 204-215, IEEE 1998. [LTWD2k] Y. Labiche, P.T. Fosse, H. Wasselynck, M.H. Durand, “Testing Levels for Object Oriented Software”, pg 136-145, ICSE 2000. [McG94] J.D. McGregor, "Functional Testing Of Classes", In 7th International Software Quality Week, San Francisco, CA., May 1994. [McK94] J.D. McGregor, T.D. Korson, "Integrating OO Testing And Development Processes", Comm of ACM, Sept 1994. [PK90] D.E. Perry, G.E. Kaiser, "Adequate Testing And Object-Oriented Programming", Journal of Object-Oriented Programming, 2:13-19, Jan./Feb. 1990. [TR95] C.D. Turner and D.J. Robson, "A State-Based Apporach To The Testing Of ClassBased Programs", Software Concepts and Tools, 16(3): 101-112, 1995. [TX96] T.H Tse, Z Xu, "A Formal Framework For Improving Object-Oriented Software Testing", 13th International Conference On Testing Computer Software, Washington

15

16

DC, 1996. [Weyu98] E. J. Weyuker, "Testing Component-Based Software: A Cautionary Tale", IEEE Software, Sept/Oct 1998. [Win98] M. Winter, “Managing Object Oriented Integration And Regression Testing (without becoming drowned)”, EuroSTAR, Munich, Germany, 1998.

16