Oct 19, 1993 - Email: kungjgaojhsia@cse:uta:edu. Jeremy Lin, Yasufumi ... The rst two activities are performed using a class regression test model, called the object ...... 70. Pattern. 118. SpaceManager. 23. ColorRep. 71. Perspective. 119.
Class Firewall, Test Order, and Regression Testing of Object-Oriented Programs David C. Kung, Jerry Gao, Pei Hsia Department of Computer Science and Engineering The University of Texas at Arlington P. O. Box 19015, Arlington, TX 76019-0015 Telephone: (817) 273-3627 Fax: (817) 273-3784 Email: @ kungjgaojhsia
cse:uta:edu
Jeremy Lin, Yasufumi Toyoshima Fujitsu Network Transmission Systems, Inc. October 19, 1993 Abstract: Regression testing is an important activity in software maintenance. Although a
number of existing research results have addressed the problems and solutions in regression testing of traditional programs, no research results have focused on the issues and solutions in regression testing of object-oriented programs. In this paper, we present a method for identifying the aected classes when changes are made to an object-oriented program. An algorithm for generating a desirable order to test the aected classes also is described. The basic model we use is an object relation graph, which depicts the inheritance, aggregation, and association relations that exist in the object-oriented program to be maintained. The test order nding algorithm can be applied to acyclic as well as cyclic object relation graphs. The results of this paper has been implemented and applied to testing of many example applications, including the InterViews library.
1 Introduction Regression testing involves re-testing part of a software system after it is modi ed. The modi cation may be caused by speci cation, or code change. The objective of regression testing 1
is to ensure that the modi ed program still satis es its requirements. To save eort and time, regression testing needs only re-test those parts that are aected by the modi cation. Regression testing has to address four fundamental problems: 1) how to automatically identify the aected components due to changes of some components; 2) what strategy should be used to retest these aected components; 3) what are the coverage criteria for re-testing these components; and 4) how to select, reuse, and modify the existing test cases (and generate new ones). Solutions to these problems for traditional programs have been proposed during the last two decades (e.g., [Fischer 1981] [Harrold 1988] [Harrold 1989] [Laski 1992] [Leung 1990] [Prather 1987] [White 1992]). However, testing of OO programs has received very little attention; regression testing of OO programs has received almost none. The object-oriented paradigm for software development introduces a number of new concepts, such as class, inheritance, encapsulation, dynamic binding, and polymorphism. These new concepts result in complex relationships between classes and their members. They not only introduce new testing problems as recognized in [Harrold 1992] [Perry 1990] [Smith 1990] [Wilde 1991], but also raise a new challenging question of how to conduct regression testing for object-oriented programs. Although the existing results can be applied to regression testing of member functions of a class at the unit and integration levels, they are not suitable for testing components at higher levels, such as a class, a group of classes, or class libraries. First, traditional approaches do not address the complex relationships and dependencies, such as inheritance, aggregation, and association, that exist between classes. Second, most traditional approaches are based on the control ow model, but class objects have state dependent behavior that can change in various ways; and hence, traditional approaches cannot be applied to class testing. Third, traditional approaches use test stubs to simulate the modules that are invoked but in OO programs this is dicult and costly because it requires understanding of many related classes, their member functions, and how the member functions are invoked [Smith 1990] [Wilde 1992]. In this paper, we propose a method for regression testing of OO programs. The underlying process of the method consists of four activities: 1) change analysis to identify aected components; 2) retest strategy generation to produce a cost-eective class test order; 3) test case reuse, modi cation, and generation; and 4) regression test plan implementation to retest the modi ed program. This paper only provides detailed technical solutions for problems in the rst two activities. The rst two activities are performed using a class regression test model, called the object relation graph (ORG). It describes the inheritance, aggregation and association relations and captures the dependencies between the classes. We de ne a class rewall to enclose all the classes aected by changes to one or more classes. The algorithm for computing the rewall is transitively derived using the dependencies. We introduce a new, cost-eective test strategy (called test order), which is derived also from the dependencies, to provide the tester with a detailed road map for conducting retests of classes in the rewall. 2
The organization of this paper is as follows. Section 2 gives a brief review of previous solutions to the four fundamental problems in regression testing. In section 3, we present an object relation graph (ORG) as a test model for class level regression testing. In section 4, the concept of a class rewall is introduced to enclose all aected classes when changes are made to one or more classes. Moreover, a method for constructing class rewalls is also described. Section 5 is devoted to test strategy generation, i.e., nding the most cost-eective test order for testing the classes in a class rewall. Application of our results to the InterViews class library is presented in section 6. In section 7, we give conclusions and future work.
2 Related Work In this section, we brie y review existing work on regression testing, discuss problems, and relate our work to the existing ones. General discussions on regression testing can be found in [Leung 1989] [Hartmann 1988]. Existing solutions to the four fundamental problems described in section 1 are discussed in the following paragraphs. The rst problem is automatic identi cation of aected modules or parts. Harroldet al. [Harrold 1988] introduced a technique for analyzing the change eects within a module. The idea is using a data- ow graph to identify the aected de nition-use pairs and/or subpaths. The advantage of this approach is that test eort is reduced by re-testing only the aected de ne-use paths and new paths. The technique was later extended so that it can also be used to identify aected procedures at the interprocedural level [Harrold 1989]. Unlike Harrold's technique, a number of researchers proposed dierent methods based on a control ow graph of a procedure/function to identify the aected control paths in a module [Laski 1992] [Benedusi 1988] [Prather 1987]. At the module integration level, H. K. J. Leung and L. White [Leung 1990] introduced the rewall concept to enclose the aected modules due to a module modi cation. The notion of a control related rewall is de ned based on a call graph. Eort is reduced by re-testing only the modules and links in the rewall of the changed module. The notion of a data related rewall was also introduced by the same authors [White 1992]. It is based on a data- ow graph to enclose all aected modules due to coupling through global data. The second problem of regression testing is nding a cost-eective test sequence for conducting retests so that test eort and costs are minimized. The well-known test strategies include the top-down, bottom-up, and sandwich approaches [Beizer 1990]. These approaches rely on the tester to make the selection. Prather et al [Prather 1987] proposed an adaptive path pre x software testing strategy that utilized previous test paths as a guide in the selection of subsequent paths. Their method ensures branch coverage and consumes fewer computational resources. Harrold et al [Harrold 1992] presented an incremental OO testing methodology based on class inheritance hierarchy. The approach suggests that base class should be tested before derived classes so that the base class' test cases and relevant information can be reused 3
in testing the derived classes. The third problem of regression testing concerns coverage criteria. Fischer, and Prather et al, respectively, described the various retest criteria relating to path coverage of a function/procedure [Fischer 1977] [Fischer 1981] [Prather 1987]. Leung and White used rewalls as a re-testing criteria at module level to ensure that all aected modules and links between modules will be retested [Leung 1990] [White 1992]. The last problem relates to how to the selection, reuse, and modi cation of existing test cases for re-testing. Fischer described a test case selection strategy which takes the form of a set covering problem [Fischer 1977] [Fischer 1981]. The basic idea is using the concept of 0-1 integer programming models to nd the minimum test cases which covers one of the path criteria in unit regression testing. Lee and He also used the 0-1 integer programming model on a test matrix to minimize test eorts in functional regression testing [Lee 1990]. Leung and White proposed a Retest Strategy for performing corrective regression testing in [Leung 1989]. The main idea is to view regression testing as composed of two subproblems: the test selection problem and the test plan update problem. Thus, the re-testing process is divided into two phases: test classi cation and test plan update. After the existing test cases are classi ed into: reusable tests, obsolete tests and retestable tests in the test classi cation phase, only retestable test cases and new test cases are considered as tests in the new regression test plan. The existing methods can be applied to regression testing of member functions [Fiedler 1989]. Traditionally, testing uses test stubs and drivers to simulate the called functions and calling functions. In OO testing, this is both costly and dicult, because the tester has to understand a chain of member functions and classes before he can construct a stub or driver. In this paper, we only address the rst two problems of regression testing of object-oriented programs; viz. identi cation of aected modules or parts, and nding a a cost-eective test sequence. The last two will be addressed in future publications. Our solution to identifying aected classes has been in uenced by Leung and White's rewall concept for modules. However, our approach aims at identifying the aected classes instead of modules. This problem has not been addressed in the literature and its complexity, as discussed in section 1, calls for innovative solutions. As a testing strategy, we propose to nd a desirable order, called class test order, to test the aected classes. The dierence between our test order and that described in [Harrold 1992] is that we take into consideration not only the inheritance relationship, but also the aggregation, and association relationships. The notion of class test order and its associated algorithms as presented in this paper can be applied to not only class inheritance hierarchies, but also class libraries, and application programs.
3 The Class Regression Test Model The class regression test model, called the object relation graph (ORG), is introduced to represent the inheritance, aggregation, and association relationships between the classes. It 4
is used to identify the aected classes (when one or more classes are changed) and generate a cost-eective test order for testing the aected classes. The ORG is only a part of our formal test model, which describes also the control structure of the member functions and the state dependent behaviors of the objects. A detailed description of the complete formal test model can be found in [Kung 1993]. Before we proceed to describe ORG, we rst brie y review the inheritance, aggregation, and association concepts used in OO modeling [Booch 1991] [Rumbaugh 1991]. The purpose is to provide the necessary background for those readers who are not familiar with the OO paradigm. We also provide simple examples to illustrate these relations in C++.
3.1 Class Relations The three most widely used class relations in OO modeling are the inheritance, aggregation, and association relations [Booch 1991] [Rumbaugh 1991] [Coad 1990] [Korson 1990]. Inheritance means properties de ned for an object class are automatically de ned for all of its subclasses (unless selective and/or overriding inheritance are speci ed). Aggregation means an object class is \part-of" or contained in another object class. Association means some kind of connection between two classes. For example, a person owns a car can be considered an association between a Person instance and a Car instance. C++ provides direct support for inheritance. For example, Car is a subclass of Vehicle can be de ned as class Vehicle f ... g; class Car: public Vehicle f ... g; where \f ... g" denotes the code that de nes the data members and function members that are speci c to the class. The de nition means 1) Car inherits the type de ned for Vehicle; and 2) all the public accessible data members and function members of Vehicle are also public accessible members of Car. Other access controls such as private and protected are also supported by C++ but it is beyond the scope of this paper to present these. The reader is referred to [Stroustrup 1991] [Lippman 1991]. Aggregation can be implemented in C++ using member data. For example, Car has one engine, four tires, and other components as its parts can be de ned as follows: class Engine f ... g; class Tire f ... g; class Car f Engine e; // car has an engine Tire t[4]; // car has four tires // other components g; Another way of implementing aggregation is to have the aggregate object dynamically create 5
the component objects. For example, a book contains chapters, some of which may be unknown before the book is completed: class Chapter f // de ne a Chapter object class char* title; Chapter* next; // pointer to next chapter, if any // other data members // ... g; class Book f char* title; // title of book Chapter* rst chapter, last chapter; // a book consists of a list of Chapters // ... g; void Book::add chapter (char* title, //...) f //add a new chapter Chapter *chap = new Chapter; // dynamically creates a new chapter chap.title = title; // lls in chapter information //... last chapter.next = chap; // appends the chapter to the book chap ! next = 0; last chapter = chap; g In this example, the Chapters are created by Book, they are part-of Book, not independent objects. Unlike aggregation, association represents more general relationships or connections between objects. Either of the related objects is not a part of the other. The objects relate themselves through access to others objects' data, or through message passing. Consider, for example, the Person owns Car association. In this, neither Person nor Car is part of the other. One way of implementing this is: class Car f ... g; class Person f Car *mycar; // relates person to car through a pointer // ... ... g; void Person::add ownership (Car *p) f // ... p ! next = mycar; mycar = p;
g
In this case, Car is not part of Person and it may also be owned by the person's spouse. It should be pointed out that these examples are not meant to exhaust all cases. However, 6
the regression test model described in the next section does take into consideration all the possible combinations. In summary, the inheritance relation can be easily extracted because these are explicitly de ned in C++. The aggregation relation involves code that includes other object class as part of the aggregate class, or code that dynamically creates objects of the component classes. In the case of association, the related object classes are not part of one another, and the related objects not created by the object. These are the principles that we use in the development of the regression test model.
3.2 Notion of Object Relation Graph An object-relation graph, called ORG, is de ned below to capture the relationships between dierent classes and their objects. De nition 1. An edge labeled digraph G = (V; L; E ) is a directed graph, where V = fV1; :::; Vng is a nite set of nodes, L = fL1; ::Lk g is a nite set of labels, and E V V L is the set of labeled edges. De nition 2. The ORG for an OO program P is an edge labeled directed graph (or digraph in short) ORG = (V; L; E ), where V is the set of nodes representing the object classes in P, L = fI; Ag; Asg is the set of edge labels, and E = EI S EAG S EAS is the set of edges de ned below. De nition 3. EI V V L is the set of directed edges representing the inheritance relation between the classes. For any two classes C1; C2 2 V , < C1; C2; I >2 EI if and only if one of the following declarations appears in the header les of P:
\class C1: C2" or \class C1: private C2". \class C1: public C2". \class C1: protected C2".
De nition 4. EAG V V L is the set of directed edges representing the aggregation relation between the classes. For any two classes C1; C2 2 V , < C1; C2; Ag >2 EAG i one of the following declarations appears in the source les of the program P:
class C1 f...
C2 b; // an instance of C2 is part of C1 C2 c [m]; // an array of instances of C2 is part of C1
... g; appears in the header les of the program P. This is called automatic aggregation. 7
class C1 f...
static C2 b; // a static instance of C2 is part of C1 static C2 c [m]; // a static array of instances of C2 is part of C1 ... g; appears in the header les of the program P. This is called static aggregation. class C1 f... C2 *b; // a dynamically created instance of C2 is part of C1 static Class C *c [m]; // an array of dynamically created instances of C2 is part of
C1
...g; appears in the header les of the program P. This is called dynamic aggregation, and C1::C1 () f // dynamically creating b; // dynamically creating c [m]; g; appears in some source le.
C1 (); // constructor for C1
De nition 5. EAS V V L is the set of directed edges representing the association relation between the classes. For any two classes C1; C2 2 V , < C1; C2; As >2 EAS i one of the following declarations appears in the source les of the program P:
class C1 accessed some data member of class C2. This type of dependencies can be
recognized in the following declarations: (1) C1::f(...) f ... if (b.d relational operator data value) f // b is an object of class C2, d is a data member of b. // b has been de ned or created outside the scope of class C1. ...g; (2) C1::f(...) f... if (p!d relational operator data value) f // p is an object of class C2, d is a data member of b. p has been de ned outside the scope of class. ...g; there is a message passing between C1 and C2. This type of dependencies can be recognized in the following declarations: (1) class C1 f ... ...f(... C2 b, ...); // b has been de ned outside of the scope of class C1 and // passed as a parameter to C1. ... g; 8
Vehicle
I Car Ag
?
Engine
? ? ? As ZZ ZZAg ZZ~
Person
Tire
Figure 1: An ORG Example (2) C1::f(...) f... ...b.f(...)...; // b is an object of class C2, and is de ned outside the scope of class C1. ...g; (3) C1::f(...) f... ...p!f(...)...; // p is an object pointer of class C2, //the object pointed out by p has been de ned outside the scope of class C1. ...g; As an example, Figure 1 depicts an ORG which represents the relationships between the classes de ned in section 3.1. They are: Car, Vehicle, Engine, Tire, and Person.
4 Class Firewall After a change is made in an object-oriented program, regression testing involves re-testing components at dierent levels: class members, classes/objects, and subsystems and systems. In order to save eort and time, regression testing needs to re-test only those components which are aected by the modi cation. There are various levels of changes, such as, data member change, function member change, class change, relation change. Each of these changes has dierent eects on the modi ed program. In this paper, we de ne class rewall as a mechanism to identify the eect of a class change. It is assumed that the relations between classes are not changed. The problem associated with class relation change will be addressed elsewhere. 9
4.1 The Notion of a Class Firewall Intuitively, a class rewall for a class C, denoted as CFW (C ), in an OO program/library is the set of classes that could be aected by changes to C. Clearly, these classes should be retested when C is changed. We wish to point out that the notion of rewall de nes the classes that are possibly be aected, not necessarily be aected. Lemma 1: Let class A be a subclass of class B in the inheritance hierarchy, and only class B is changed. For adequate testing, not only should class B be unit retested, but also class A be retested with class B together if the change has eect on inherited members of class A. Proof: Since class A is a subclass of class B, class A must inherit some of class B's attributes. Thus, class A has a code dependency on class B. The modi cation made in class B can aect the behaviors of class A's objects in the following two out of three cases:
the change is made on one or more de ned members of class B which are inherited by class A. the change is made on one or more de ned members of class B which has a direct or indirect eect on inherited members of class A. the change has no direct or indirect eect on inherited members of class A.
Therefore, in the rst two cases, class A should be unit retested to make sure that its de ned members and inherited members behave correctly and interact correctly with each other. For all three cases, re-integrating test is needed for classes A and B to guarantee that all class A's members inherited from class B properly in the reuse context. Lemma 2: Let class A be a aggregate class of class B in the aggregation hierarchy, and only class B is changed. For adequate testing, not only should class B be unit retested, but also class A be retested together with class B. Lemma 3: Let class A in the association hierarchy be associated to class B in one of the following two ways: (1) class A accesses class B's data members; (2) class A has a message passing to class B. If class B is changed, for adequate testing, not only should class B be unit retested, but also class A be retested and re-integrated with class B.
4.2 Constructing a Class Firewall To compute the class rewall, we rst introduce a binary relation R that is derived from the directed edges of an ORG = (V; L; E ): (1) R = f< C2; C1 > jC1; C2 2 V ^ (9l)(l 2 L^ < C1; C2; l >2 E )g We will call R the dependence relation since it de nes the dependence between the classes, according to the inheritance, aggregation, and association relations. More speci cally, < 10
C2; C1 >2 R if and only if one of the following cases holds: 1) C1 is a derived class of C2; 2) C1 is an aggregate class of C2, i.e., C2 is part of C1; or 3) C1 is associated with C2 either by accessing its data members, or passing some messages. In all these cases, C1 is dependent on C2 in the sense that code changes to C2 would aect the behavior of C1. The computed class rewall for a class C, denoted CCFW (C ), then is de ned as CCFW (C ) = fCj j < C; Cj >2 Rg where R is the transitive closure of R. That is, if < Ci; Cj >2 R and < Cj ; Ck >2 R, then < Ci; Ck >2 R. The transitive closure of R can be computed by the famous Warshall
algorithm [Aho 1983]. Theorem 1: Let G be an ORG of a given OO program P, R be the dependence relation derived from G. Let C be a class in which a change is made to its de ned or rede ned members. Assume the dependencies between the classes of P are the dependencies of inheritance, aggregation, and association relations. Then, CCFW (C ) = CFW (C ), that is 1. CCWF (C ) CFW (C ). 2. CFW (C ) CCFW (C ). Proof(1): We want to prove that for any class Ci 2 CCFW (C ), class Ci could be aected by the changes to class C, and should be retested. The proof is by induction on n of dependence relation Rn .
Basis: For any class Ci, < C; Ci >2 R1. Then < Ci; C; l > 2 E of G based on the de nition of R. Thus, < Ci; C; l > must be one of the three cases: inheritance edge, aggregation edge, or association edge. According to Lemma 1, 2 and 3, in all these cases, Ci could be aected by changes to C, and Ci should be retested. Inductive Hypothesis: Assume that for any class Cj , < C; Cj >2 Rk . Then class Cj would be aected by changes to class C, and should be retested. Inductive Step: We need to prove that for any class Ci, if < C; Ci >2 Rk+1 , then class Ci could be aected and should be retested. According to the transitive nature of R, there must be < Cj ; Ci >2 R and < C; Cj >2 Rk . From the inductive hypothesis, class Cj could be aected by the changes to class C, and should be retested. From the basis, class Ci could be aected by the changes of class Cj , and should also be retested. Thus, class Ci could be aected by the changes to class C, and should be retested. Proof(2): We want to prove that if any class Ci , Ci 2 CFW (C ), then class Ci 2 CCFW (C ). We prove this using contradiction. Assume there is class Ci which is not in CCFW (C ), but Ci 2 CFW (C ) in the sense that it could be aected by the changes to class C and should be retested. 11
Since class Ci could be aected by the change of class C only when Ci is either directly or indirectly dependent on the de ned members of class C. Thus, there must be one dependency chain (denoted CHAIN ) : f< Ci; Cj1 >; :::; < Cjk ; C >g, from class Ci to class C. As we known, the types of dependency between two classes/objects can be classi ed into: (1) code dependency; (2) object dependency; (3) control dependency; (4) data or state dependency. According to the assumption, they are dependencies of the three relations: inheritance, aggregation, and association. Hence, CHAIN R, and < Ci; C >2 R. Therefore, < Ci; C >2 CCFW (C ). This is a contradiction. QED. According to theorem 1, the following theorem can be easily derived. Theorem 2: Let CCFW(C) be the computed rewall for class C. For any class Ci, if Ci is not in CCFW (C ), then, Ci is not aected by the change in class C and hence, no retest is needed. Using theorem 1, we can construct the class rewall for a changed class to enclose all possible aected classes which should be retested. According Weyuker's axioms for adequate testing[Weyuker 1986] and Perry's work[Perry 1990], these classes should also be re-integrated with their subclasses, aggregated classes and associated classes to achieve adequate testing. The detailed results for class integration test strategy is provided in the next section. The notion of the class rewalls can be extended to a set of changed classes. Let S = fC1; C2; : : :; Ck g be a set of classes (that are changed). Then, the class rewall for S , also denoted CFW (S ), is de ned as follows:
CFW (S ) =
[ 8C 2S
CFW (C )
As an example, Figure 2 depicts an ORG for a subset of classes in the InterViews library, and Figure 3 depicts the class rewall for the class Subject in the subset.
5 Test Order for Class Firewalls After identifying the class rewall for a changed class, the tester needs a cost-eective strategy to conduct the retests for each class at the class unit level and re-integrate classes together at the class integration level. The existing test strategies, including top-down, bottom-up, and sandwich, rely on the tester to make the selection , and conduct the unit and integration tests by using test stubs and test drivers. However, in regression testing of OO programs, it is costly and dicult to construct test stubs and drivers for a class object or a class function member due to the following reasons. First, simulating a class or its objects is very costly and dicult because the tester not only has to understand and simulate its class members, object states and behaviors, but also has to understand and simulate its inherited members and component class objects. Second, 12
1 Sensor QkQQ 6 QQ Ag Ag As As Q As QQ = ? Scene - Event Button Z As ? 6@ 6 ZZAs ? @ I? I Ag ZZ @@ ? ~ Z As I ? @@ TextButton As - ButtonState As ? ? @R World ? Ag - Canvas ?? ?I As ? ? ? H YHH Subject ? Control HH I CanvasRep 6 HH I 6 S HHHj SS MonoScene H As HH As As HHH Ag S ? ? InteractorItr ControlState SS ButtonList
As
Ag
Figure 2: An ORG Example for a Subset of Classes in InterViews Library simulating a member function is also very expensive and complicated because the test has to understand chains of member function invocations and simulate the dierent state changes of class objects and messages between the class objects due to these function invocations1 to construct appropriate test stubs. In addition, according to [Wilde 1991], 80% member functions consist of one or two statements. Thus, if we can test components using tested components by following a proper test sequence, then the test eorts for constructing test stubs and test drivers can be reduced. The main idea is to test the independent components rst, then test the dependent components based on their relationships. For example, testing the called functions before the calling function, then the eort required to construct the test stub for the calling function can be saved. Similarly, testing a base (or aggregated) class before the subclasses (or assembly classes), then the stub for the base classes (or the aggregated classes) can be reduced for testing the subclasses (or assembly classes). Moreover, the test information for the base class (or the aggregated class) can be reused in testing its subclasses (assembly classes). In order to resolve this problem, we introduce a test strategy, called test order, to serve as a detailed road map in class unit re-testing and class re-integration testing. The test order problem for class rewalls can be stated as nding a desirable order for testing Unlike a procedure in the conventional programs, a function member of a class can not be viewed as a function from its input domain to output domain, instead it only changes the states of class objects or passes the message between objects. 1
13
1 Sensor QkQQ QQ Ag As Ag As Q As QQ = ? Scene ZZButton ZZZZ Event ? 6@ 6 ZZZAs As ? @ I? Ag I ZZ @ ? @ ~ Z As I ? ZTextButton @ ZZZZZ As - ZButtonState ZZZZZ As ? @@ ? ? ? World Canvas R ? Ag ? I As ? ? ? Z ZZZZ? ZZZControl H YHH ZSubject ZZZ HHHI CanvasRep 6 HH I 6 S HHj SS MonoScene H As HH As As HHH Ag S ? ? ZZZZZZ ZZZZZZ SS InteractorItr ControlState ZButtonList ZZZZZ 6
Legend:
ZZZZZZ Changed
As
ZZZZZZ Aected
Figure 3: A Class Firewall for Class Subject in a Subset of InterViews Library
14
Ag
the classes that are aected by code changes to a set of classes. By testing of a class, we mean structure testing, function testing, object state testing, and/or data ow testing of the member functions of the class. Exactly how these testings are performed is beyond the scope of this paper. A desirable test order also implies eective reuse of previously generated test cases in the new, reusing context. In [Harrold 1992], Harrold, McGregor, and Fitzpatrick proposed a methodology for reusing test cases in the testing of a class hierarchy, i.e., involving only inheritance relations. Our result on test order supplements their work and allows test cases to be reused in a more general context, where inheritance, aggregation, and association relations exist. The above discussion implies that a desirable test order is one that requires minimum eort to construct the test stubs. Since the eorts to construct the test stubs dier substantially from case to case, we will assume that the total eort is proportional to the number of stubs need to be constructed. The reader will see later that this assumption will not aect the usefulness of the method, since it can be easily tailored to take into consideration the eorts required to construct individual stubs. A solution to the test order problem must consider two cases: 1. The ORG = (V; L; E ) is an acyclic digraph, meaning that there exists no cycle in the digraph. A cycle is a directed path leading from one node, traversing directed edges, back to itself. 2. The ORG = (V; L; E ) is a cyclic digraph, meaning that there exists one or more cycles. In this case, topological sorting cannot be applied. In the rst case, the test order is simply the topological sorting of CCFW (S ) using the dependence relation R (de ned in section 4) as the precedence relation. The computational complexity is O(jCCFW (S )j), i.e., the number of classes in the rewall for S , since each node needs to be visited only once [Aho 1983]. The eort required to construct the test stubs is zero and hence it is minimum. The solution to case 2 is nontrivial since topological sorting cannot be applied to cyclic digraphs. The remainder of this paper is devoted to developing a solution for this case.
5.1 Overview of the test Order Finding Algorithm The algorithm is based on two key concepts. The rst is the notion of a cluster, which is a maximal set of vertices that are mutually reachable through the relation R de ned in section 42. Note that a cyclic ORG may have more than one cluster, and a cluster may contain only one vertex (such clusters are called unit clusters). A cyclic digraph ORG = (V; L; E ) can be 2
This is also called strongly connected subgraph in graph theory.
15
transformed into an acyclic digraph ORG0 = (V 0; L0; E 0) in which V' is the set of clusters in the ORG, E' is the set of edges between clusters in the ORG, L' is the set of labels on edges in E'. It can be proved that ORG0 must be acyclic; otherwise, some of the clusters must not be a maximal set of mutually reachable vertices. We will not pursue a proof in this paper due to space limit. Since ORG0 is acyclic, topological sorting can be applied to produce a test order for the clusters. The test order is called the major test order, to distinguish from the minor test order (described below) produced for the vertices of a cluster. The second notion is cycle breaking, that is, to identify and temporally remove an edge(s) from a non-unit cluster so that the vertices of the cluster and their associated edges form an acyclic subgraph. Again, topological sorting can be applied to the acyclic subgraph to derive a test order, called the minor test order. Thus, a cyclic ORG can be tested rst according to the major test order and then the minor test order. We are now ready to outline the algorithm:
Step 1. Transform the ORG into an acyclic digraph ORG0 . Step 2. Produce a topological sorting for the ORG0 . The test order produced is called the major test order. Step 3. For each non-unit cluster of ORG0 do steps 4 to 5. Step 4. For each cycle of the cluster, select and remove an edges to break the cycle. Step 5. Produce a topological sorting for the acyclic subdigraph obtained in step 4. The test order produced is called the minor test order.
Note the above algorithm applies to acyclic as well as cyclic digraphs. If the digraph is acyclic, then steps 3 to 5 are not performed. Among the ve steps, only steps 1 and 4 require elaboration since the other steps are straight forward. 3. Therefore, in the following sections, we will focus on converting a cyclic digraph to an acyclic one, and strategies for selecting an edge to break a cycle.
5.2 Converting a Cyclic ORG to an Acyclic ORG Using Clusters The algorithm uses the transitive closure of the dependence relation R de ned in section 3. As usual the transitive closure is denoted R . For any two vertices u; v 2 V , where V is the vertex set of the original cyclic ORG = (V; L; E ), < u; v >2 R means code change to u would aect the behavior of v, and < u; v >2 R means v is transitively aected by code change to u. Clearly, if < u; v >2 R and < v; u >2 R, then changes to u aect v and vice versa. In There are algorithms for step 1, we adapt them in the next section for readers who might not be familiar of them. 3
16
this case, u and v are mutually reachable and they are in a cycle. Therefore, u and v must be placed in the same cluster. Since the mutually reachable relation is an equivalence relation (i.e., re exive, symmetric, and transitive), we follow the usual mathematical convention and denote the cluster that contains u as [u]. The purpose of this algorithm is to identify such pairs and place them in a cluster, and compute the edges that de ne the precedence relation between the clusters: Input: ORG = (V; L; E ) Output: an acyclic digraph ORG0 = (V 0; L0; E 0), where V 0 fv0jv0 2 2V g L0 fl0jl0 2 2Lg E 0 = f< u0; v0; l0 > j(u0 v0 l0) T E 6= ;g
Step 1. Initialize. Let [v] 2 V 0 for every v 2 V , L0 = E 0 = ;, and each vertex of V
is marked unclustered (the marking will be changed to clustered when the vertex is placed into an established cluster). We assume that the vertices of ORG are indexed as v1; v2; : : : ; vn. Any indexing scheme can be used, since it is not essential. Step 2. Compute R . Compute the transitive closure, denoted R, for R = f< vi; vj > jvi; vj 2 V ^ (9l)(l 2 L^ < vj ; vi; l >2 E )g Step 3. Compute clusters. For i = 1 to n ? 1, do the following if vi 2 V is marked unclustered: For j = i + 1 to n, if < vi; vj >2 R and < vj ; vi >2 R, then 1. insert v into the cluster containing v , i.e., set [v ] = [v ] Sfv g; j
i
2. mark vj as clustered; and 3. delete [vj ] from V 0, i.e., set V 0 = V 0 ? f[vj ]g.
i
i
j
Step 4. Compute the edges E 0. For each pair u0; v0 2 V 0, if there is a directed edge from
some vertex in u0 to some vertex in v0 in the original digraph, then create a directed edge from u0 to v0, the label for this directed edge is the union of all the labels of the original edges. This is formally computed by the following formula: E 0 = f< u0; v0; l0 > ju0; v0 2 V 0 ^ l0 2 L0 ^ (u0 v0 l0) T E 6= ;g
In illustration, Figure 2 shows a cyclic ORG for a subset of InterViews library, and Figure 4 the acyclic ORG0 produced by this algorithm.
5.3 Breaking a Cycle Given a cyclic ORG, such as the vertices and the associated edges in a cluster, how can one determine a test order to test the classes that are mutually dependent on each other? 17
'
$
'
$
1 Sensor Qk ButtonList QQ 6 QAsQ Ag Ag As As QQ QScene = ? - Event Button As Z ? @6@ &I 6 Z% ? ZZAs I ? @@ Z ? ~ As As - Z I As ? @@ TextButton ButtonState As ? Ag ? @ World ? R H ? HH & % ? H I H ' $ ' $ Ag ? HHHj ? ? H Subject ? Control H Canvas CanvasRep YHH HHI As 6As HHHI 6 S H H j HH As As Ag S S MonoScene HHH ? ? SS InteractorItr ControlState S
&
%
&
Ag
%
Figure 4: The acyclic ORG' for the subset of the InterViews library Our answer to this question is to break the cycle(s) by temporally removing some of the directed edges. This leads to the second question, that is, which edge(s) are to be removed ? Our answer is to remove association edges since among the three relations discussed in this paper, association relation represents the weakest coupling between the two related classes. The other two relations, i.e., inheritance and aggregation, involve not only control coupling, but also code dependence and data coupling. The following theorem provides the basis for cycle breaking of association edges: Theorem 3. Every directed cycle of an ORG contains an association edge. The proof of the theorem is lengthy and can be found in [Gao 1993]. The basic idea is that inheritance and aggregation represent a part-of relation between the data spaces of the objects of the two related classes (top-down part-of for inheritance, and bottom-up part-of for aggregation). Moreover, these two relations are transitive relations. Object creation at run time would lead to data space explosion and causes undesired side-eect. Therefore, the program will not work properly. If there are more than one association edge that can be removed to break a cycle, then which one to be removed would aect the test eort. One possible solution is to introduce the cardinality concept to object relation graphs (ORG) to represent the number of class members that are involved in the association relation between two classes. However, we will not pursue this issue here. Our current implementation is simply picking up any association 18
' $ l 1 QkQ QQ l6
QQ l QQ = ?
Z ? @6@ &6 Z% ? ZZ ? l @@ l ZZ ? -~ @@ ?? @R Q?Q ?? & % ? Q ' ' $ $ QQ l ? l ? QQs ? l l H ? YHH H l 6 HHH 6 l S HHHHj SS HH HHH l l ? ? SS l S & % & % '
$ l 4
ButtonList
As
4.1
As
I
As
3.1
As
As
3.2
3.4
Event
As
TextButton
Sensor
Ag
Ag 4.2
Button
5
3
Scene
I
2
ButtonState
As
As
3.3
I
I
Ag
5
Subject 1.1
As
As
1.2
InteractorItr
Ag
Ag
World
1
As
I
Control
As
5.2
1
I
Ag
CanvasRep
As
2
Canvas
MonoScene
5.1
4
ControlState
Figure 5: Test order for the subset of the InterViews library edge and removing it until no cycle exists. After breaking the cycles in each cluster, topological sorting can be applied to produce a test order. Figure 5 shows the major test order and minor test order for the InterViews example shown in Figure 4. The test order suggests that the classes be tested in the following order: Subject, InteractorItr, CanvasRep, ButtonState, Canvas, Sensor, Scene, World, Event, ButtonList, Button, MonoScene, TextButton, ControlState, Control. Since the generated test order is a topological order, it is possible that two or more vertices may have the same number. For example, the vertices Canvas and ButtonState in Figure 5 have the same major test order which is 2. In this case, either of them can tested before the other.
5.4 Test Order Based Regression Test Strategy Test Order for Re-Testing Each Class During regression testing, the previous test order algorithm can be used to nd a costeective test order for the classes in a class rewall. Then, the generated test order is used as a guideline to select individual classes to conduct retests at the class unit level. Figure 6 shows the generated test order of the rewall for class Subject in Figure 3. The testing is carried out by following the major test order to test each cluster of classes. If the cluster to 19
be tested is a unit cluster, then its to be tested is a unit cluster4, then the member functions of the class in the cluster are tested according to their invocation dependencies. That is, if member function g invokes member function f , then f is tested before g. If recursive calls do not exist among the member functions, then topological sorting can be applied to produce a test order for testing the member functions. Otherwise, the termination condition for the recursive calls is identi ed and tested rst, followed by testing of the other cases recursively. We do not address member function test order, interprocedural testing, and testing of recursive functions in this paper. The interested reader is referred to [Hwang 1988] [Harrold 1991] and other publications. If the cluster to be tested is a non-unit cluster5, then the classes in the cluster are tested according to the minor test order. Since the classes are cyclically dependent on each other, it is not possible to test all the member functions of each of the classes according to the minor test order in one pass. Therefore, the classes are tested in two or more passes. The trick is to test, in each pass, the member functions of a class that do not invoke other untested member functions. This process is repeated until all the member functions are tested. If recursion does not exist among the member functions of the classes, then two passes suce; otherwise, recursive, multiple passes are needed. The retest for a class may include: function member testing (both white-box or black-box), object state testing, and data- ow testing. The purpose is to check the dierent aspects of the target class, including its function members, objects states and behaviors, data ows.
Test Strategy for Class Re-Integration The generated test order for a class rewall can also be used as a test strategy for class reintegration. Class re-integration can be conducted based on the test order in the following steps: 1. build the initial system S by using the unaected classes. 2. integrate S with the changed class C after it is tested. 3. follow the major test order to pick one class or one cluster to be re-integrated with S. If the chosen cluster has more than one classes, then they will be re-integrated following the minor test order. The purpose of class re-integration testing is to check if the classes, which are related to each other or dependent on each other, can work together properly. The focus of this testing are: inherited members, aggregated parts, state dependent behaviors, and message passing between dierent objects. Similar to class unit testing, the generated test order indicates the re-integration order for the classes in the rewall. 4 5
a unit cluster is a cluster which has only one class a non-unit cluster is a cluster which consists of more than one classes
20
'
$ 1 Sensor ZButtonList Z Z QkQQ Cluster 2 Z ZZ 1.1 6 2 Ag QQ Ag As As Q As QQ 1.2 =
?Z Z Scene - Event ZZButton ZZZ As ? 6@@ 6 Z ? Z% &I I? Ag ZAsZ 1 @@ ? ~ Z As I ? ZTextButton @@ ZZ ZZZ As - ZButtonState ZZZZZ As ? ? ? @R World ? - Canvas 3 ?I? ' Ag $ As ? 1 ? ZZZControl ? Z ZZZZ? H YHH ZSubject ZZZHH HI CanvasRep 6 HH I 6 1.2 SS HHj H As
H As As H SS MonoScene H 1.1 Ag H
H ZZ? S Z?ZZZZZ 1 ZZZZ S InteractorItr ControlState Cluster 1& % Legend:
ZZZZZZ
Changed
ZZZZZZ Aected
Figure 6: The Test Order for the Firewall of Class Subject
21
As
Ag
6 A Large Example We have implemented an object-oriented testing environment using the reverse engineering approach [Kung 1993]. In the testing environment, a test support tool, called rewall identi er, is developed based on the class rewall concept to automatically identify all possibly aected classes for a changed class. After a class rewall is recognized, a test order generator, which is designed based on the results of this paper, is used to nd the desired cost-eective test order for re-testing the aected classes. The generated test order provides not only a cost-eective class unit retest strategy, but also a detailed class re-integration strategy. We have applied this tool to many applications, including the InterViews library. The InterViews library contains 147 les, more than 140 classes, and more than 400 relationships. Appendix A lists lists the classes in the InterViews library, and Appendix B shows the the inheritance, aggregation and association relationships between these classes. Without the automatic support, it is very dicult for a regression tester to identify the relations between the classes. How to conduct regression testing for this library when changes are made to one or more classes? For example, when a change is made in class Canvas, the regression tester will face the rst challenge of identifying the aected classes. The tester only has two choice: either retest all classes, or manually nd out statically or dynamically as the tests are performed. Both choices are costly and undesirable. The rewall identi er program of the OOT environment provides one automatic solution to nd all possibly aected classes for re-testing. For a changed class CanVas, the identi ed class rewall is shown in Figure 7. After identifying the class rewall for a changed class, the tester starts to conduct the retests for the classes in the rewall. The rst task is to retest each aected class at the class unit level. But, which class the tester should begin with ? Without a detailed guideline and automatic support tools, he will encounter another challenge: very costly test stubs. For example, if the Button class is chosen to be tested at rst, then as shown in Figure 7, the test stubs, for classes: Sensor, ButtonState, Event and ButtonList, are needed. For constructing the test stub of ButtonState, the tester needs to understand some other classes, such as Subject, InteractorItr because the relationships between them. This fact suggests that a cost-eective strategy is needed for retest classes at the class unit level to save the test cost. The similar problem is also encountered by the tester when he performs the class re-integration tests. Thus, the real challenge problem the tester deals with are: 1) what is the cost-eective strategy for class unit retests ? 2) what is the desirable strategy for class re-integration ? The test order generator in the OOT environment automatically generates a cost-eective test order for the classes in the rewall, so that the test cost on constructing test stubs for class unit regression testing and class re-integration testing is reduced. The lists below show the classes in the rewall for the Canvas class and the generated cost-eective test order for these classes. During class unit retests, the generated test order can be used as a strategy 22
to help the tester to nd a cost-eective test sequence. Later, the test order can be used as a desirable step wise road map for class re-integration to reduce the test cost. Firewall for the InterViews Canvas class class ID 1 2 5 6 7 10 13 14 16 18 20 25 26 28 31 32 33 34 38 41 42 43 44 45 46
class name Adjuster Banner Border BorderFrame Box BoxElement Button ButtonList Canvas Card CheckBox Control ControlState Deck Dialog DownMover Enlarger Event FileChooser Frame Glue GrowingBSpline GrowingClosedBSpline GrowingMultiLine GrowingPolygon
class ID 47 48 49 50 51 52 53 54 55 56 57 58 60 61 68 69 71 76 77 78 79 80 81 82 86 87
class name GrowingVertices HBorder HBox HGlue HScroller Interactor InteractorItr LeftMover MarginFrame Menu MenuBar MenuItem MonoScene Mover Painter Panner Perspective PulldownMenu PullrightMenu PushButton RadioButton Raster RasterRep Reducer RightMover RotatingLine
class ID 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 111 112 113
class name RotatingLineList RotatingRect RubberAxis RubberCircle RubberClosedSpline RubberEllipse RubberGroup RubberHandles RubberLine RubberPointList RubberRect RubberSpline RubberSquare RubberVertex Rubberband ScalingLine ScalingLineList ScalingRect Scene Scroller Sensor ShadowFrame ShowFrame Slider SlidingEllipse
class ID 114 115 116 117 119 120 121 122 126 130 131 132 133 134 136 137 138 139 140 141 142 143 144 145 146
class name SlidingLine SlidingLineList SlidingPointList SlidingRect StretchingRect StringBrowser StringChooser StringEditor Subject TextButton TextDisplay TextEditor TitleFrame TopLevel Tray UpMover VBorder VBox VGlue VScroller ViewList Viewport World WorldView Zoomer
The Test Order of Classes in the Firewall for Canvas Class class name Canvas RasterRep Raster Painter Event Sensor Interactor TopLevel Scene World ViewList Perspective Adjuster Banner Border BoxElement Card Glue MonoScene Rubberband Scroller Slider TextDisplay Tray WorldView Subject InteractorItr Box Deck Frame GrowingVertices HBorder HGlue HScroller Mover Panner RotatingRect RubberEllipse RubberGroup RubberLine RubberPointList RubberRect
major order 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
minor order 1 2 3 4 5 6 8 9 10 11 12 13 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
class name DownMover Enlarger GrowingBSpline GrowingClosedBSpline GrowingMultiLine GrowingPolygon HBox LeftMover MarginFrame Menu MenuItem Reducer RightMover RotatingLine RubberAxis RubberCircle RubberSquare RubberVertex ScalingLine ScalingLineList ScalingRect ShadowFrame ShowFrame SlidingEllipse SlidingLine SlidingPointList SlidingRect StretchingRect StringBrowser StringEditor UpMover VBox ButtonList Button BorderFrame FileBrowser MenuBar PulldownMenu PullrightMenu RotatingLineList RubberClosedSpline RubberHandles
23
major order 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5
minor order 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0
TextEditor VBorder VGlue VScroller Viewport Zoomer ControlState Control Dialog
3 3 3 3 3 3 3 3 4
0 0 0 0 0 0 1 2 0
RubberSpline SlidingLineList StringChooser TextButton TitleFrame CheckBox FileChooser PushButton RadioButton
5 5 5 5 5 6 6 6 6
0 0 0 0 0 0 0 0 0
7 The Regression Test Process Regression testing can be carried out with respect to dierent levels of change and dierent types of change to an OO program. The levels of change include changes to member data, to member functions, to classes, and to subsystems or libraries. The types of change include changes to data values, to member function signatures, to conditional statements, and so on. It is beyond the scope of this paper to address the entire spectrum of changes and describe a total regression test process. Instead, we brie y describe a regression test process based on the results we have presented in this paper. The regresssion test process consists of the following iterative phases: Identi cation of Changed Classes. In this phase, the tester compares the original program and the modi ed program to identify classes that are changed. This can be easily achieved by using a code comparator. Identi cation of Aected Classes. In this phase, the tester identi es aected classes. This is achived by computing the class rewall(s) for the classes that are changed. Generation of a Class Test Order. In this phase, the tester generates a class test order to facilitate test case preparation and the actual conduct of regression testing. By using the algorithm and tool presented in this paper, this task can be easily accomplished. Selection of Test Cases. In this phase, the tester selects test cases to retest the aected classes. This is done according to the test order and by consulting the test plan if one exists. The test order speci es which classes should be tested before which other classes so that eort needed to construct test drivers and test stubs can be saved. It also facilitates test case reuse, meaning that some test cases of a class may be reused by its dependent class. For example, in certain circumstances, a test case for a member function of a superclass, say the rotate function of polygon, can be reused to test the same function inherited by a subclass, say rectangle. A test plan contains test cases that were previously designed to test the original program. Test cases that were designed to test the aected classes are selected. Test Case Modi cation and Generation. In this phase, the tester modi es the selected test cases and generates new test cases according to the changes made. For example, if changes have been made to change the structure of the original program without aecting its functionality, then the relevant structural test cases are modi ed so that the required coverage criteria can be met. If the functionality of the original program has been enhanced, then 24
the relevant functional test cases are modi ed and perhaps new test cases are generated to test the new functionality. The result of this phase is a new test plan, which contains the modi ed test cases and the new test cases. Regression Test Execution. In this phase, the tester prepares test data according to the test cases and execute the modi ed program using the test data. The test results then are analyzed and documented. The modi ed program is tested at dierent levels: unit class testing, class integration testing, and system testing. In unit class testing, the classes in the rewall(s) are tested according to the test order, while in class integration testing, the classes are integrated according to the test order. Again, since the test order is generated according to the dependencies between the classes, using the test order to guide unit class testing and class integration testing will reduce the eort needed to construct the test drivers and test stubs.
8 Conclusions and Future Work We have discussed the regression processes and addressed problems in regression testing of object-oriented programs. We have presented methods for nding the aected classes when changes are made to some classes of a C++ program. We also presented a test order generation algorithm to provide a cost-eective test sequence of components to serve as a road map for a tester to retest classes in the class rewall. The results can be used to conduct cost-eective regression testing of classes at the class unit level and the class integration level. These techniques have been incorporated in our object-oriented testing environment and have been applied to realistic applications, like the InterViews class library. The results so far are promising. We are currently investigating guidelines for nd a rewall of a changed class member, and algorithms for testing the member functions of the classes.
9 Acknowledgment This research is supported by Fujitsu Network Transmission Systems, Inc. and HewlettPackard Company. The authors want to thank the other members of the Object-Oriented Testing Team, K. Chang, M. Cheng, S. Ha, K. Huang, J. Samuel, Y. Song, and N. Suchak, for many stimulating discussions and their eort to implement the environment.
10 References [Aho 1983] A. V. Aho, J. E. Hopcroft and J. D. Ullman, \Data Structures and Algorithms," Addison-Wesley Publ. Comp., 1983. 25
[Beizer 1990] B. Beizer, \Software Testing Techniques," 2nd ed., Van Hostrand Reinhold, 1990. [Benedusi 1988] P. Benedusi, A. Cimitile, and U. De carlini, \Post-maintenance testing based on path change analysis," Proc. IEEE Conf. on Software Maintenance, pp. 352 { 361, 1988. [Booch 1991] G. Booch, \Object-Oriented Design with Applications" Redwood City, Calif.: Benjamin/Cummings, 1991. [Coad 1990] P. Coad and Yourdon, E. \Object-oriented Analysis." Yourdon Press, 1990. [Fiedler 1989] S. P. Fiedler, \Object-oriented unit testing," Hewlett-Packard Journal, pp. 69 - 74, April 1989. [Fischer 1977] K.F. Fischer, "A Test Case Selection Method for the Validation of Software Maintenace Modi cations", IEEE COMPSAC 77 Int. Conf. Procs., pp. 421-426, No. 1977. [Fischer 1981] K.F. Fischer, F. Raji and A. Chruscicki, "A Methodology for Re-Testing Modi ed Software", National Telecomms. Conf. Procs., pp. B6.3.1-6, Nov. 1981. [Gao 1993] Jerry Gao, \Test Order for Object-Oriented Programs," Technical Report No. 93-1, Software Engineering Center for Telecommunications, The University of Texas at Arlington, 1993. [Harrold 1988] M. J. Harrold and M. L. Soa, "An incremental approach to unit testing during maintenance", Proc. Conf. Software Maintenance, pp. 362-367, Phoenix, 1988. [Harrold 1989] M. J. Harrold and M. L. Soa, "Interprocedural data ow testing", Proc. Conf. Software Maintenance, pp. 362-367, Phoenix, 1988. [Harrold 1991] M. J. Harrold and J. D. McGregor, \Toward a testing methodology for objectoriented software systems," Department of Computer Science, Clemson University. [Harrold 1992] M. J. Harrold, J. D. McGregor, and K. J. Fitzpatrick, \Incremental testing of object-oriented class structure", Proc. of 14th International Conf. on Software Engineering, 1992. [Hartmann 1988] J. Hartmann and D. J. Robson, "Approaches to Regression Testing", Proc. Conf. Software Maintenance, pp. 368-372, 1988. [Hwang 1988] J. C. Hwang, M. W. Du, and C. R. Chou, \Finding program slices for recursive procedures," Proc. of 9th International Conf. on Software Engineering, pp. 220 { 227, 1988. [Laski 1992] Janusz Laski and Wojciech Szermer, "Identi cation of Program Modi cations and its Applications in Software Maintenance", Proc. Conf. Software Maintenance, pp. 282-290, 1992. [Korson 1990] T. Korson and J. D. McGregor. \Understanding object- oriented: a unifying paradigm." CACM Vol. 33, No. 9, pp. 40 - 60, Sept. 1990. 26
[Kung 1993] D. Kung, \The behavior network model for conceptual information modeling." Journal of Information Systems, Vol. 18, No. 1, pp. 1 { 21, 1993. [Lee 1990] J. Lee and X. He, \A methodology for test selection," Journal of Systems and Software, Vol. 13, pp. 177 - 185, 1990. [Leung 1989] H.K.N Leung and L. White, "Insights into regression testing", Proc. Conf. Software Maintenance, pp. 60-69, Miami, FL, Oct. 1989. [Leung 1990] H. K. N. Leung and L. White, \A study of integration testing and software regression at the integration level," Proc. IEEE Conf. on Software maintenance, pp. 290 { 301, 1990. [Lippman 1991] S. B. Lippman, \A C++ Primer," Reading, Mass: Addison-Wesley, 1991. [Perry 1990] D. E. Perry and G. E. Kaiser, \Adequate testing and object-oriented programming," Journal of Object-Oriented Programming, Vol. 2, pp. 13 - 19, January/February 1990. [Prather 1987] Ronald E. Prather and J. Paul Myers, JR, "The Path Pre x Software Testing Strategy", IEEE Transactions On Software Engineering, Vol. SE-13, NO. 7, July 1987. [Rumbaugh 1991] J. Rumbaugh et al., \Object-Oriented Modeling and Design," PrenticeHall, 1991. [Smith 1990] M. D. Smith and D. J. Robson, \Object-oriented programming | the problems of validation," Proc. IEEE Conference on Software Maintenance | 1990. pp. 272 { 281. [Stroustrup 1991] B. Stroustrup, \The C++ Programming Language", 2nd ed., AddisonWesley, 1991. [Weyuker 1986] E. J. Weyuker, \Axiomatizing software test data adequacy," IEEE Trans. on Software Eng., Vol. SE-12, No. 12, pp. 1128 - 1138, 1986. [White 1992] L. White and H.K.N. Leung, "A Firewall Concept for both Control-Flow and Data-Flow in Regression Integration Testing", Proc. Conf. Software Maintenance, pp. 262271, 1992. [Wilde 1991] N. Wilde and R. Huitt, \Issues in the maintenance of object-oriented programs," University of West Florida and Bell Communications Research, 1991. [Wilde 1992] N. Wilde and R. Huitt, \Maintenance support for object-oriented programs," IEEE Trans. on Software Eng., Vol. 18, No. 12, pp. 1038 - 1044, Dec. 1992.
27
Appendix A: Class List for the InterViews Library Number of Files = 147; Number of Classes = 146; Number of Relationships > 400. class ID 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
class name Adjuster Banner Bitmap BitmapRep Border BorderFrame Box BoxCanonical BoxDimension BoxElement Brush BrushRep Button ButtonList ButtonState Canvas CanvasRep Card Catalog CheckBox ChiefDeputy Color ColorRep Connection Control ControlState Cursor Deck DefaultProps Deputy Dialog DownMover Enlarger Event EventList FBDirectory FileBrowser FileChooser Font FontRep Frame Glue GrowingBSpline GrowingClosedBSpline GrowingMultiLine GrowingPolygon GrowingVertices HBorder
class ID 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
class name HBox HGlue HScroller Interactor InteractorItr LeftMover MarginFrame Menu MenuBar MenuItem Message MonoScene Mover ObjectSpace ObjectStub ObjectTable ObjectTableEntry OptionDesc Packet Painter Panner Pattern Perspective PopupMenu PropertyData PropertyDef PropertySheet PulldownMenu PullrightMenu PushButton RadioButton Raster RasterRep Reducer Regexp ReqErr Resource RightMover RotatingLine RotatingLineList RotatingRect RubberAxis RubberCircle RubberClosedSpline RubberEllipse RubberGroup RubberHandles RubberLine
class ID 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
class name RubberPointList RubberRect RubberSpline RubberSquare RubberVertex Rubberband ScalingLine ScalingLineList ScalingRect Scene Scroller Sensor ShadowFrame Shape ShowFrame Slider SlidingEllipse SlidingLine SlidingLineList SlidingPointList SlidingRect SpaceManager StretchingRect StringBrowser StringChooser StringEditor StringId StringPool StringTable Subject TGlue Table TextBuer TextButton TextDisplay TextEditor TitleFrame TopLevel Transformer Tray UpMover VBorder VBox VGlue VScroller ViewList Viewport World WorldView Zoomer
Appendix B: Class Relations in the InterViews Library The Inheritance Relation between Classes in InterViews Library
(class ID, (1, (61, (32, (48, (139, (130, (22, (31, (40, (541, (50, (57, (59, (70, (93, (101,
class ID, 52, 1, 61, 5, 7, 13, 85, 60, 85, 111, 42, 49, 52, 85, 102, 97,
R) R) RI ) RII ) R) RI ) RII ) R) RI ) RII ) R) RII ) R) RI ) RII ) R) RII )
(class ID, (146, (54, (2, (138, (11, (78, (25, (37, (41, (109, (140, (76, (68, (71, (113, (95,
class ID, 1, 61, 52, 5, 85, 130, 60, 120, 60, 41, 42, 56, 85, 85, 93, 101,
R) R) RI ) RII ) R) RI ) RII ) R) RI ) RII ) R) RII ) R) RI ) RII ) R) RII )
(class ID, (33, (86, (3, (7, (15, (79, (26, (38, (111, (55, (58, (77, (69, (80, (91, (99,
28
class ID, 146, 61, 85, 106, 126, 130, 126, 121, 41, 41, 25, 56, 60, 85, 93, 101,
R) R) RI ) RII ) R) RI ) RII ) R) RI ) RII ) R) RII ) R) RI ) RII ) R) RII )
(class ID, (82, (137, (5, (49, (13, (20, (28, (39, (133, (42, (56 (72, (112, (102, (97, (92,
class ID, 146, 61, 52, 7, 52, 130, 106, 85, 111, 52, 25 56, 52 85, 102, 101,
R) R) RI ) RII ) R) RI ) RII ) R) RI ) RII ) R) RII ) R) RII ) RI ) R) RII )
(116, (94, (103, (117, (47, (44, (51, (118, (63, (136,
97, 102, 96, 98, 102, 47, 107, 30, 85, 106,
R) RII ) R) RI ) RII ) R) RI ) RII ) R) RII )
(115, (96, (87, (119, (45, (106, (141, (120, (126, (143,
116, 102, 96, 98, 47, 52, 107, 52, 85, 60,
R) RII ) R) RI ) RII ) R) RI ) RII ) R) RII )
(104, (90, (98, (105, (46, (60, (108, (121, (132, (144,
97, 96, 102, 98, 47, 106, 85, 31, 52, 106,
R) RII ) R) RI ) RII ) R) RI ) RII ) R) RII )
(88, (114, (100, (89, (43, (107, (62, (122, (135, (145,
104, 96, 98, 102, 47, 52, 63, 52, 85, 52,
R) RII ) R) RI ) RII ) R) RI ) RII ) R) RII )
The Aggregation Relation between Classes in InterViews Library (class ID, (68, (144, (1, (3, (13, (25, (37, (35,
class ID, 3, 39, 108, 135, 14, 108, 36, 34,
R) RAG ) RAG ) RAG ) RAG ) RAG ) RAG ) RAG ) RAG )
(class ID, (106, (144, (1, (7, (130, (28, (1,
class ID, 16, 68, 68, 10, 68, 18, 52,
R) RAG ) RAG RAG ) RAG ) RAG ) RAG ) RAG )
(class ID, (144, (145, (2, (7, (79, (28, (8,
class ID, 16, 16, 68, 52, 3, 71, 9,
R) RAG ) R ) RAG ) RAG ) AG RAG ) RAG ) RAG )
(class ID, (144, (1, (3, (13, (25, (28, (29,
class ID, 22, 71, 4, 108, 26, 52, 74,
R) RAG ) RAG ) RAG ) RAG ) RAG ) RAG ) RAG )
The Association Relation between Classes in InterViews Library (class ID, (127, (143, (10, (18, (134, (1, (13, (19, (22, (27, (30, (34, (38, (38, (133, (52, (52, (52, (52, (52, (52, (56, (56, (68, (68, (68, (112, (71, (80, (102, (106, (107, (107, (62, (62, (118, (120, (68, (25, (27, (28, (28, (31, (52, (38, (41, (111, (109, (42, (140, (144,
class ID, 110, 68, 52, 52, 52, 3, 15, 63, 23, 22, 21, 52, 52, 55, 2, 110, 106, 16, 3, 68, 134, 26, 144, 22, 11, 135, 52, 142, 81, 16, 52, 52, 108, 63, 64, 24, 131, 16, 26, 3, 68, 52, 34, 34, 15, 52, 34, 52, 68, 68, 52,
R) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS )
(class ID, (121, (122, (122, (142, (53, (65, (64, (131, (132, (1, (1, (146, (33, (82, (61, (61, (54, (86, (137, (32, (3, (68, (68, (4, (48, (7, (7, (49, (139, (139, (13, (130, (78, (79, (20, (16, (144, (96, (90, (114, (103, (87, (98, (100, (117, (119, (105, (89, (47, (45, (46,
class ID, 120, 129, 131, 52, 52, 24, 63, 68, 129, 68, 110, 68, 52, 52, 52, 34, 68, 68, 68, 68, 39, 3, 4, 135, 68, 52, 8, 110, 52, 8, 34, 15, 15, 15, 15, 22, 16, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
R) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS )
(class ID, (136, (145, (14, (134, (134, (11, (16, (21, (26, (30, (31, (34, (38, (39, (133, (52, (52, (52, (52, (52, (56, (56, (57, (68, (68, (69, (112, (80, (102, (94, (60, (107, (62, (62, (62, (120, (121, (25, (25, (27, (28, (31, (108, (37, (68, (111, (541, (55, (50, (16, (58,
29
class ID, 52, 144, 13, 27, 3, 12, 17, 24, 25, 24, 15, 144, 37, 40, 52, 27, 144, 71, 108, 123, 52, 106, 26, 70, 39, 52, 71, 22, 68, 102, 52, 71, 24, 19, 118, 15, 122, 52, 34, 39, 71, 52, 34, 15, 40, 52, 52, 52, 68, 52, 52,
R) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS )
(class ID, (121, (122, (125, (126, (53, (65, (64, (131, (132, (1, (146, (146, (33, (82, (61, (54, (86, (137, (32, (2, (3, (3, (4, (5, (138, (7, (49, (49, (139, (68, (13, (130, (78, (79, (20, (106, (145, (90, (114, (103, (87, (98, (100, (117, (119, (105, (89, (47, (45, (46, (43,
class ID, 52, 15, 123, 142, 142, 63, 65, 16, 131, 34, 52, 34, 68, 68, 68, 52, 52, 52, 52, 68, 135, 4, 39, 68, 68, 110, 52, 8, 110, 12, 68, 68, 68, 68, 68, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
R) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS )
(56, (57, (77, (69, (112, (70, (75, (68, (93, (113, (91, (97, (101, (95, (99, (92, (116, (115, (104, (88, (94, (96,
25, 25, 52, 68, 34, 3, 74, 81, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS )
(43, (44, (106, (60, (51, (51, (51, (141, (141, (120, (121, (122, (126, (53, (129, (132, (136, (136, (143, (144, (145, (52,
68, 68, 108, 108, 52, 108, 71, 68, 34, 34, 15, 34, 52, 126, 83, 71, 108, 127, 108, 66, 27, 35,
RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS )
(56, (76, (68, (112, (112, (71, (80, (81, (93, (113, (91, (97, (101, (95, (99, (92, (116, (115, (104, (88, (94,
30
34, 52, 80, 68, 110, 52, 16, 16, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS )
(44, (106, (60, (107, (51, (51, (141, (141, (141, (120, (121, (63, (126, (64, (132, (136, (136, (143, (143, (144, (145,
16, 68, 68, 68, 68, 34, 52, 108, 71, 71, 34, 24, 53, 24, 34, 68, 110, 52, 71, 73, 110,
RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS ) RAS )
Contents 1 Introduction
1
2 Related Work
3
3 The Class Regression Test Model
4
3.1 Class Relations : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 5 3.2 Notion of Object Relation Graph : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 7
4 Class Firewall
9
4.1 The Notion of a Class Firewall : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 10 4.2 Constructing a Class Firewall : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 10
5 Test Order for Class Firewalls
12
5.1 Overview of the test Order Finding Algorithm : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 15 5.2 Converting a Cyclic ORG to an Acyclic ORG Using Clusters : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 16 5.3 Breaking a Cycle : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 17 5.4 Test Order Based Regression Test Strategy : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 19
6 A Large Example
22
7 The Regression Test Process
24
8 Conclusions and Future Work
25
9 Acknowledgment
25
10 References
25
31