• No results found

CHAPTER 2 TECHNICAL DEFINITIONS

3.5 Testing

3.5.2 Generating the Test Files

The generation of the test les is carried out through an automated process described in the pseudo code in Figure 3.18. The main generated test le consists of a series of method calls to the methods in a given equivalence class. It is my hypothesis that a good approx- imation for detecting semantic equivalence between methods can be obtained by running these methods on a suciently large sample of their input domainincluding both state and argument values.1

1 Files generateTestFiles ( int numTests ){

2 HashMap < TypeAndEffects , ArrayList < MethodEntry >> equiClasses = Program . getTypeAndEffect ();

3 For each TypeAndEffects mapping in equiClasses {

4 Generate files for class

5 }

6 create driver class to run all files

7 }

Figure 3.18: Pseudo code for generating test le

To test this hypothesis, my algorithm runs multiple tests on objects in the same state and also runs each set of input parameter values with objects in multiple states. The details of how test states or contexts are created are described in Section 3.5.1 on page 53. Each method is tested with a user-dened number of test cases numTests. This is called the test set. For methods with a non-empty parameter list, numTests sets of parameter values are used. For non-static methods numTests receiver object states are used. For static methods, numTests tuples of the static elds of the class containing the method are used if such elds exist. The structure of the test le is thus determined by the methodType of the equivalence class as summarized in Table 3.5 on page 63. Pseudo code for handling cases with non-empty and empty parameter lists are given in the rst and second methods in Figure 3.20 on the following page.

1 generateFilesForEquiClass ( Equivalence class of methods grouped by type and effect class ){

2 Create class with constructor for equivalence class

3 if methodType has parameters

4 generate numTests sets of parameters

5 if has non - static methods

6 generate numTests sets of each receiver object

7 if has static fields

8 generate numTests sets of static fields

9 for i=1 to number of methods in class {

10 if( has parameters ){

11 getMethodCallStringsWithParameters ( method , parameters , states ) 12 } 13 else { 14 getMethodCallStringsWithoutParameters ( method , states ) 15 } 16 }

17 create aspect code using method call strings

18 write aspect code to files

19 }

Figure 3.19: Pseudo code for generating test les for an equivalence class

1 String getMethodCallStringsWithParameters ( method , parameters , states ){

2 for i =1 to numTests {

3 for j =1 to numTests {

4 create method call with state i and parameter set j

5 add code to store result as EffectRec in array

6 }

7 add code to Convert result array to String and hash

into result hash on resultString

8 }

9 }

10 // --- 11

12 String getMethodCallStringsWithoutParameters ( method , states ){

13 for i =1 to numTests {

14 create method call with state i

15 add code to store result as EffectRec in array

16 }

17 add code to Convert result array to String and hash

into result hash on resultString 18

19 }

For example, suppose the user-dened test-set size is 5. Then to test a non-static method A.b(c, d, e) we use 5 samples of objects of type A in dierent states. We also use 5 dierent tuples of the parameters c, d, and e. Note that this is only 5 tuples, not all combinations of 5 values for each parameter. Thus the total number of tests for method b is 5× 5 or 25.

Analyzing private methods to identify semantic clones presented a challenge: how to make calls to private methods outside of their class, when they are only visible inside of their dening class. I considered three options for handling this. The rst was to modify the code being tested, so that all methods are declared public. A second approach, like the rst, would require modifying the code in the input test classes. In this approach new public methods can be dened within a class, to call the private class methods. A third possible approach is to generate privileged AspectJ aspects. This is described in Section 2.7 on page 34. This approach presents several advantages. It facilitates the desired functionality with very little implementation eort, since existing software is reused.2 Plus there is no need to change the

code in multiple input les. Also, the use of a privileged aspect also allows access to private methods and elds without changing their visibility. Thus the AspectJ approach is adopted in this study.

For each equivalence class of candidate clones, a matching class and at least one privileged aspect are created. The class is used to instantiate the instance of the equivalence class so that its member methods can be run. The privileged aspect denes the runTest method. This is fundamentally a set of method calls to each of the methods of the equivalence class in all of the created contexts. The runTest method is dened as an advice, when the pointcut of a call to an equivalence class constructor, is encountered. The method runTest is placed in a privileged aspect to ensure that calls to private methods, would not be blocked

by Java's visibility rules. A single test-driver is also created. This is the le used to run all of the tests. It creates an instance of each equivalence class, running its runTest method as part of the equivalence class constructor. Thus it runs all of the methods under test to identify the clones.

Table 3.5: Structure of Test File MethodType Structure of Test File Empty

Parameter List

Non-Static n method calls to each method, each time with a dierent receiver object state

Static if member class has static elds, n method calls to method, each time with a dierent static eld values; Otherwise one method call to method

Non-Empty Parameter List

Non-Static n receiver objects are created, and n tuples of parameter values. In all n × n method calls are made to method. Method is called on each receiver object with each of the parameter tu- ples in turn.

Static n tuples of parameter values are created; if member class has static elds n tuples of static eld values are created. If there are static elds n × n method calls are made to method. For each tuple of static eld values, the method call is made with each of the pa- rameter tuples in turn. Otherwise the method is called n times  once with each tuple of pa- rameter values

Related documents