Post-Print Version DOI: http://doi.acm.org/10.1145/1370042.1370061

A Strategy for Evaluating Feasible and Unfeasible Test Cases for the Evolutionary Testing of Object-Oriented Software José Carlos Bregieiro Ribeiro

Mário Alberto Zenha-Rela

Francisco Fernandéz de Vega

Polytechnic Institute of Leiria Morro do Lena, Alto do Vieiro Leiria, Portugal

University of Coimbra CISUC, DEI, 3030-290, Coimbra, Portugal

University of Extremadura C/ Sta Teresa de Jornet, 38 Mérida, Spain

[email protected]

[email protected]

[email protected] ABSTRACT

1.

Evolutionary Testing is an emerging methodology for automatically producing high quality test data. The focus of our on-going work is precisely on generating test data for the structural unit-testing of object-oriented Java programs. The primary objective is that of efficiently guiding the search process towards the definition of a test set that achieves full structural coverage of the test object. However, the state problem of object-oriented programs requires specifying carefully fine-tuned methodologies that promote the traversal of problematic structures and difficult control-flow paths – which often involves the generation of complex and intricate test cases, that define elaborate state scenarios. This paper proposes a methodology for evaluating the quality of both feasible and unfeasible test cases – i.e., those that are effectively completed and terminate with a call to the method under test, and those that abort prematurely because a runtime exception is thrown during test case execution. With our approach, unfeasible test cases are considered at certain stages of the evolutionary search, promoting diversity and enhancing the possibility of achieving full coverage.

Test data selection, generation and optimization deals with locating good test data for a particular test criterion. However, locating quality test data can be time consuming, difficult and expensive; automating this process is, therefore, vital to advance the state-of-the-art in software testing. Distinct levels of testing include functional (black-box) and structural (white-box) testing. With white-box testing techniques, test case design is performed with basis on the program structure. When white-box testing is performed, the metrics for measuring the thoroughness of a given test set can be extracted from the structure of the target object’s source code, or even from compiled code. Traditional whitebox criteria include structural (e.g., statement, branch) coverage and data-flow coverage. The basic idea is to ensure that all of the control elements in a program are executed by a given test set, providing evidence of the quality of the testing activity. When performing unit-testing, individual application objects or methods are tested in an isolated environment [23]; its goal is to warrant the robustness of the smallest units – the test objects. In order to do so, the test object is executed in different scenarios using relevant and interesting test cases. A test set is said to be adequate with respect to a given criterion if the entirety of test cases in this set satisfies this criterion. Unit test cases for object-oriented (OO) software consist of method call sequences (MCS), which represent the test scenario. During its execution, all objects participating in the test are created and put into a particular state by calling several instance methods for these objects. Each test case focuses on the execution of one particular method – the method under test (MUT). In the particular case of object-oriented programs, it is not possible to test the operations of a class in isolation, as they interact with each other by modifying the state of the object which invokes them; testing a single class thus involves other classes, i.e. classes that appear as parameter types in the method signatures of the class under test (CUT). The transitive set of classes which are relevant for testing a particular class is called the test cluster for this class. However, the execution of test cases may abort prematurely if a runtime exception is thrown during execution [22]. When this happens, it is not possible to observe the structural entities traversed in the MUT because the final in-

Categories and Subject Descriptors D.2.5 [Software Engineering]: Testing and Debugging— Testing tools (e.g., data generators, coverage testing)

General Terms Verification

Keywords Search-Based Test Case Generation, Evolutionary Testing, Object-Orientation, Strongly-Typed Genetic Programming

Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. AST’08, May 11, 2008, Leipzig, Germany. Copyright 2008 ACM 978-1-60558-003-2/08/05 ...$5.00.

INTRODUCTION

struction of the MCS is not reached. Test cases can thus be separated in two classes: • feasible test cases are effectively executed, and terminate with a call to the MUT; • unfeasible test cases terminate prematurely because a runtime exception is thrown by an instruction of the MCS. The evaluation of test data suitability using structural criteria generally requires the definition of an underlying model for program representation – usually a control-flow graph (CFG). The observations needed to assemble the metrics required for the evaluation can be collected by abstracting and modelling the behaviours programs exhibit during execution, either by static or dynamic analysis techniques. Dynamic analysis involves executing the actual test object and monitoring its behaviour. Dynamic monitoring of structural entities can be achieved by instrumenting the test object, and tracing the execution of the structural entities traversed during execution. Instrumentation is performed by inserting probes in the test object; in Java software, this operation can be effectively performed at the Java bytecode level. Java bytecode is an assembly-like language that retains much of the high-level information about the original source program. Given that the target object’s source code is often unavailable, working at the bytecode level allows broadening the scope of applicability of software testing tools; they can be used, for instance, to perform structural testing on thirdparty Java components. The focus of our on-going work [15, 16, 17] is precisely that of employing evolutionary algorithms for generating test cases for the structural unit-testing of third-party OO Java programs. With our approach, test cases are represented and evolved using the Strongly-Typed Genetic Programming (STGP) paradigm [13], which effectively mimics the inheritance and polymorphic properties of objectoriented programs and enables the maintenance of call dependences when performing tree construction, mutation or crossover. The application of evolutionary algorithms to test data generation is often referred to as evolutionary testing [10, 11] or search-based test case generation [5]. In evolutionary testing, meta-heuristic search techniques are employed to select or generate test data. The search space is the input domain of the test object, and the problem is to find a set of test cases that satisfies a certain test criterion. Evolutionary algorithms have been applied successfully to the search for quality test data in the field of object-oriented unit-testing. Approaches have been proposed that focus on the usage of Genetic Algorithms [20], Ant Colony Optimization [8], Universal Evolutionary Algorithms [21], Genetic Programming [19], Strongly-Typed Genetic Programming [22, 23], and Memetic Algorithms [1] . One of the most pressing challenges faced by researchers in this area is the state problem [12], which occurs with methods that exhibit state-like qualities by storing information in internal variables that are protected from external manipulation. The encapsulation aspect of the object-oriented paradigm, in particular, constitutes a serious hindrance to testing [3], because the only way to observe the state of an object is through its operations, and the only way to change the state of an object’s internals is through the execution of

a series of method calls. Defining a test set that achieves full structural coverage may thus involve the generation of complex and intricate test cases in order to define elaborate state scenarios. This paper’s main objective is that of presenting a novel strategy for test case evaluation, which intends to efficiently guide the evolutionary search process towards achieving full structural coverage. Our methodology involves allowing unfeasible test cases to be considered at certain stages of the evolutionary search – namely, once the feasible test cases that are being bred cease to be interesting – so as to achieve a good compromise between the intensification and the diversification of the search. In the following Section, we start by reviewing the related work in the area of OO evolutionary testing, with the intention of framing our proposal into this research field. Next, our search-based test cased generation procedure is detailed, with special attention being paid to the test case evaluation strategy. The concepts presented were implemented into the eCrash automated test tool, which is also introduced in Section 3; eCrash was employed for performing a series of experiments, detailed and discussed in Section 4, with the intention of assessing the impact and benefits of our test case evaluation methodology. The concluding Section resumes the key ideas of this paper.

2.

RELATED WORK

A first approach to the field of evolutionary testing of object-oriented software was presented by Tonella [20]; in this work, input sequences for the white-box testing of classes were generated using evolutionary algorithms. Genetic Algorithms was the evolutionary approach employed, with possible solutions being represented as chromosomes. A sourcecode representation was used, and an original evolutionary algorithm, with special evolutionary operators for recombination and mutation on a statement level – i.e. mutation operators insert or remove methods from a test program – was defined. A population of individuals, representing the test cases, was evolved in order to increase a measure of fitness, accounting for the ability of the test cases to satisfy a coverage criterion of choice. New test cases were generated as long as there were targets to be covered or a maximum execution time was reached. However, the encapsulation problem was not addressed, and this proposal only dealt with a simple state problem. Additionally, this approach employed custom-made operators and original evolutionary algorithms and, as such, Universal Evolutionary Algorithms (i.e. evolutionary algorithms, provided by popular toolboxes, which are independent from the application domain and offer a variety of predefined, probabilistically well-proven evolutionary operators) could not be applied. An approach which employed an Ant Colony Optimization algorithm was presented in [8]. The focus was on the generation of the shortest method call sequence for a given test goal, under the constraint of state dependent behaviour and without violating encapsulation. Ant PathFinder, hybridizing Ant Colony Optimization and Multiagent Genetic Algorithms were employed. To cover branches enclosed in private/protected methods without violating encapsulation, call chain analysis on class call graphs was introduced. In [21] the focus was put on the usage of Universal Evolutionary Algorithms. An encoding was proposed that represented object-oriented test cases as basic type value struc-

tures, allowing for the application of various search-based optimization techniques – such as Hill Climbing or Simulated Annealing. The test cases generated could be transformed into test classes according to popular testing frameworks (e.g., JUnit). Still, the suggested encoding did not prevent the generation of individuals which could not be decoded into test programs without errors; the fitness function used different penalty mechanisms in order to penalize invalid sequences and guide the search towards regions that contained valid sequences. Due to the generation of invalid sequences, the approach lacked efficiency for more complicated cases. In [19], a methodology for creating test software for objectoriented systems using a Genetic Programming approach was proposed; the author stated that this methodology was advantageous over the more established search-based testcase generation approaches because the test software is represented and altered as a fully functional computer program. However, it was pointed out that the number of different operation types is quite limited, and that large classes which contain many methods lead to huge hierarchical trees. In [22, 23] a Strongly-Typed Genetic Programming based approach (which is of particular interest to our studies) was presented. Potential solutions were encoded using a STGP methodology, with MCS being represented by method call trees; these trees are able to express the call dependences of the methods that are relevant for a given test object. To account for polymorphic relationships which exist due to inheritance relations, the STGP types used by the function set are specified in correspondence to the type hierarchy of the test cluster classes. The emphasis of this work was on sequence validity; the usage of STGP preserves validity throughout the entire search process, with only compilable test cases being generated. The fitness function does need, however, to incorporate a penalty mechanism for test cases which include method call sequences that generate runtime exceptions. The issue of runtime exceptions was precisely the main topic in [22]. Recently, Arcuri et al. [1, 2, 18] have developed work focused on the testing of Container Classes (e.g., Vector, Stack, Red-Black Tree). Besides analysing how to apply different search algorithms (Random Search, Hill Climbing, Simulated Annealing, Genetic Algorithms, Memetic Algorithms and Estimation of Distribution Algorithms) to the problem and exploiting the characteristics of this type of software to help the search, more general techniques that can be applied to object-oriented software were studied. To the best of our knowledge, these works performed test object analysis with basis on target program’s source-code; moreover, instrumentation and event tracing is also performed at the source-code level. We are not aware of existing evolutionary approaches to the unit-testing of objectoriented software that employ Java bytecode analysis to derive structural testing criteria. The application of evolutionary algorithms and Java bytecode analysis for test automation was, however, already studied in different scenarios. In [4] an attempt to automate the unit-testing of objectoriented programs was described; a functional approach for investigating the use of Genetic Algorithms for test data generation was employed, and program specifications written in JML were used for test result determination. The JML compiler was extended to make Java bytecode produce test coverage information. In [14] the layout of a symbolic JVM, which discovered test cases using a definable structural cov-

erage criterion with basis on static analysis techniques, was described. The bytecode was executed symbolically, and the decision whether to enter a branch or throw an exception was based on the earlier constraints, a constraint solver and the current testing criterion. The symbolic JVM has been implemented in a test tool called GlassTT. This work, however, did not address exception-related and method interactionrelated criteria, and only procedural software scenarios were described.

3.

METHODOLOGY

In this Section, our evolutionary approach for automatic test case generation is described. The concepts presented were implemented into the eCrash tool, which was employed to assess the impacts of the proposed test case evaluation strategy (Section 4). Figure 1 summarizes the main phases of the process, which are described with further detail in [16, 17]. In Subsection 3.1, special attention will be given to the test case evaluation procedure. Static Analysis and Instrumentation Phase Test Object Analysis Test Cluster Definition CFG Definition Function Set Definition Parameter and Function Files Generation Test Object Instrumentation foreach MUT Weight Initialization foreach Generation Weight Reevaluation Phase foreach Individual Test Case Generation Phase foreach STGP tree STGP tree linearization MCS generation Test Case Generation Test Case Compilation Test Case Evaluation Phase Test Case Execution Structural Event Tracing Feasible/Unfeasible Test Case Evaluation Individual’s Fitness Definition Figure 1: Methodology overview. With our approach, the first task is that of performing static analysis on the test object; it is in this step that the test cluster and the function set are defined, and hence it must precede the evolving and evaluation phases. The static analysis process is performed at the Java bytecode level; control-flow graphs are used as the underlying model for representing the methods under test, and are built with basis on the information extracted from the Java bytecode of the test object. In order to enable the observation of the CFG nodes transversed during a given program execution, the test object’s bytecode is instrumented for basic block analysis and structural event dispatch with the aid of the Sofya framework [6]. Test cases are represented as STGP individuals; each individual contains a number of STGP trees equal to the number of arguments of the method under test – i.e., each STGP tree provides an object that will be used as an argument for the MUT’s call. This encoding is especially suited, as it effec-

tively mimics the inheritance and polymorphic properties of OO programs and enables the generation of compilable test cases. Each tree subscribes to a function set, which defines the STGP nodes legally permitted in the tree, and is specified beforehand in correspondence to the constraints of the test cluster classes. For evolving test cases, the Evolutionary Computation in Java (ECJ) package [9] is used. ECJ is a research package that incorporates several Universal Evolutionary Algorithms and includes built-in support for Set-Based STGP. The first step involved in the generation of the test cases’ source-code is the linearization of the STGP trees using a depth-first transversal algorithm. The tree linearization process yields the method call sequence (e.g., Figure 2). Sourcecode generation is performed by translating method call sequences to test cases, using the method signature information encoded into each STGP node; Figure 3 depicts an example of a test case generated by the eCrash tool.

3.1

Test Case Evaluation

Metaheuristic algorithms require a numerical formulation of the test goal, from which a fitness function can be derived. The purpose of the fitness function is to guide the search into promising, unevaluated areas of the search space. With our approach, the quality of a given test case is related to the CFG nodes of the MUT which are the targets of the evolutionary search at the current stage of the search process; test cases that exercise less explored (or unexplored) CFG nodes and paths must be favoured. However, the execution of test cases may abort prematurely if a runtime exception is thrown during execution. When this happens, it is not possible to trace the structural entities transversed in the MUT because the final instruction of the MCS is not reached. Test cases that fall into this class are referred to as unfeasible test cases – as opposed to feasible test cases, which are effectively executed and terminate with a call to the MUT. As a general rule, longer and more intricate test cases are more prone to throw runtime exceptions; however, complex method call sequences are often needed for defining elaborate state scenarios and transversing certain problem nodes. If unfeasible test cases are blindly penalized, the definition of complex test cases will be disencouraged. The issue of steering the search towards the traversal of interesting CFG nodes and paths was address by assigning weights to the CFG nodes; the higher the weight of a given node the higher the cost of exercising it, and hence the higher the cost of transversing the corresponding control-flow path. Let each CFG node n ∈ N represent a linear sequence of computations (i.e., Bytecode instructions) of the MUT; each CFG edge eij represents the transfer of the execution control of the program from node ni to the node nj . Conversely, nj is a successor node of ni if an edge eij between the nodes ni and nj exists. The set of successor nodes of ni is defined as Nsni , Nsni ⊂ N .

3.1.1

Weight Reevaluation

The weight of transversing node ni is identified as Wni . At the beginning of the evolutionary search the weights of nodes are initialized with a predefined value Winit . The CFG nodes’ weights are reevaluated at the beginning of every generation according to Equation 1.

 Wni = (αWni )

hitCni +1 |T |



P

x∈Nsni Wx ni |Ns | × Winit 2

! (1)

The hitCni parameter is the “Hit Count”, and contains the number of times a particular CFG node was exercised by the test cases of the previous generation. T represents the set of test cases produced in the previous generation. The constant value α, α ∈]0, 1] is the weight decrease constant. In summary, at the beginning of each generation the weight of a given node is multiplied by: • the weight decrease constant value α, so as to decrease the weight of all CFG nodes indiscriminately; • the hit count factor, which worsens the weight of recurrently hit CFG nodes; • the path factor, which improves the weight of nodes that lead to interesting nodes and belong to interesting paths. After being reevaluated, the weights of all the nodes are normalized in accordance to Equation 2. Wni =

Wni × Winit Wmax

(2)

Wmax corresponds to the maximum value for the weight existing in N .

3.1.2

Evaluation of Feasible Test Cases

For feasible test cases, the fitness is computed with basis on their trace information; relevant trace information includes the “Hit List” – i.e., the set Ht , Ht ⊆ N of transversed CFG nodes. The fitness of feasible test cases is, thus, evaluated as follows: P F itnessf easible (t) =

3.1.3

h∈Ht

Wh

|Ht |

(3)

Evaluation of Unfeasible Test Cases

For unfeasible test cases, the fitness of the individual is calculated in terms of the distance between the runtime exception index exIndt (i.e., the position of the method call that threw the exception) and the method call sequence length seqLent . Also, an unfeasible penalty constant value β is added to the final fitness value, so as to penalise unfeasibility.

F itnessunf easible (t) = β +

(seqLent − exIndt ) × 100 (4) seqLent

With this methodology, and depending on the value of β and on the fitness of feasible test cases, unfeasible test cases may be selected for breeding at certain points of the evolutionary search, thus favouring the diversity and complexity of method call sequences. This will happen if feasible test cases always transverse recurrently hit nodes, thus increasing their weight and worsening the fitness of the corresponding test cases. The following experimental study and its concluding remarks will help clarifying this statement.

Figure 2: Example of a STGP tree (genotype) and the corresponding MCS (phenotype).

Figure 3: Example test case.

Function Name boolean empty() boolean empty() Object peek() Object peek() Object pop() Object pop() Object push(Object) Object push(Object) int search(Object) int search(Object) int search(Object) Stack() Object() “HelloWorld!” null

Return Type boolean Stack Object Stack Object Stack Object Stack int Stack Object Stack Object Object Object

Child Types Stack Stack Stack Stack Stack Stack Stack, Object Stack, Object Stack, Object Stack, Object Stack, Object -

Table 1: Function Set for the Stack test object.

4.

EXPERIMENTAL STUDY

In this case study, experiments were performed on Stack class of the java.util package of JDK 1.4.2. Its public API is composed by five public methods, namely boolean empty(), Object peek(), Object pop(), Object push(Object item) and int search(Object o); all of them were subjected to the test case generation process. The rationale for choosing this test object is related with the fact that, being a container class, the Stack class has the interesting property of containing explicit state, which is only controlled through a series of method calls. Additionally, it allows us to demonstrate the applicability of the approach to a “real world” problem. Nevertheless, the main objective of this study is that of experimenting with different configurations for the probabilities of evolutionary operators – mutation, reproduction and crossover – and for the values of the test case evaluation parameters – the weight decrease constant α (Equation 1) and the unfeasible penalty constant β (Equation 4). The static analysis process yielded the Function Set depicted in Table 1. For evolving test cases, ECJ was configured using a single population of 5 STGP individuals. The MUTs’ CFG nodes were initialized with a weight Wni of 200. The search stopped if an ideal individual was found or after 200 generations. For the generation of individuals a multi-breeding pipeline was used, which stored 3 child sources; each time an individual had to be produced, one of those sources was selected with a predefined probability. The available breeding pipelines were the following: a Reproduction pipeline, which simply makes a copy of the individuals it receives from its source; a Crossover pipeline, which performs a stronglytyped version of Subtree Crossover [7] – two individuals are selected, a single tree is chosen in each such that the two trees have the same constraints, a random node is chosen in each tree such that the two nodes have the same return type, and finally the swap is performed; and a Mutation pipeline, which implements a strongly-typed version of Point Mutation [7] – an individual is selected, a random node is selected, and the subtree rooted at that node is replaced by

a new valid tree. The selection method employed was Tournament Selection with a size of 2.0, which means that first 2 individuals are chosen at random from the population, and then the one with the best fitness is selected.

4.1

Probabilities of Operators

This particular experiment was performed with the intention of assessing the implications of evolutionary operators’ probabilities on the test case generation process. In order to do so, 4 distinct parametrizations of the multi-breeding pipeline were defined, having: a high probability of selecting the mutation pipeline; a high probability of selecting the crossover pipeline; a high probability of selecting the reproduction pipeline; equal probabilities of selecting either pipeline. The weight decrease constant α was set to 0.9, and the unfeasible penalty constant β was defined as 150. It should be noted that the definition of these values was heuristic, as no experiments had been performed that allowed a fundamented choice; these were conducted later, and are described in the following Subsection. For each of the above multi-breeding pipeline parameterizations, 20 runs were executed for each of the 5 MUTs. Table 2 summarizes the results obtained. The results depicted clearly show that the strategy of assigning balanced probabilities to the all of the breeding pipelines yields better results. Configuration #4 (r:0.33 c:0.33 m:0.34) was the only one in which full coverage was achieved in all of the runs (in, at most, 200 generations), and it was also the best in terms of the average number of generations required to attain it. The worst results were obtained for the parameterization in which the reproduction breeding pipeline was given a high probability of selection. For the Object push(Object item) and int search(Object o) MUTs – which pose the most challenging problems in terms of state complexity – 43% of the runs failed to attain full coverage within 200 generations.

4.2

Evaluation Parameters

In this experiment, different combinations of values for the α and β parameters were tried out, with the intention of analysing the impact of the test case evaluation parameters on the evolutionary search. The following values were used: • α – 0.1, 0.5, and 0.9; • β – 0, 150, and 300. The probabilities of choosing the 3 breeding pipelines were chosen in accordance to the results yielded by the experiment described in Subsection 4.1 – i.e., the probabilities for reproduction, crossover and mutation were set to 0.33, 0.33 and 0.34 respectively. All the 9 combinations of the α and β values were employed, and 20 runs were executed for each (in a total of 180 runs); full coverage was achieved in all of the runs. The results obtained are summarized in Table 3, which includes the average number of generations required to attain full coverage for each of the 5 MUTs using each combination. These results clearly show that the best configuration for the test case evaluation parameters is that of assigning a low value to α (0.1 and 0.5 yielded the best results) and a value of approximately 150 to β.

MUT empty peek pop push search

r:0.1 c:0.1 m:0.8 %full #gens 100% 10.2 100% 6.6 100% 6.5 100% 20.6 95% 48.9

r:0.8 c:0.1 m:0.1 %full #gens 100% 11.2 100% 10.7 100% 8.9 57% 16.4 57% 48.2

r:0.1 c:0.8 m:0.1 %full #gens 100% 17.5 100% 9.4 100% 8.6 95% 37.2 82% 98.8

r:0.33 c:0.33 m:0.34 %full #gens 100% 4.5 100% 2.8 100% 2.8 100% 2.5 100% 18.7

Table 2: Statistics for the Probabilities of Operators case study. Relevant data includes the probabilities of choosing the reproduction (r ), crossover (c) and mutation (m) pipelines and, for each configuration, the percentage of runs in which full coverage was achieved (%full ) and the average number of generations required attain full coverage (#gens).

empty peek pop push search average

α = 0.1 5.2 3.0 2.8 5.2 17.5 6.7

β=0 α = 0.5 5.5 3.5 3.2 5.2 18.4 7.1

α = 0.9 4.8 3.4 3.1 5.2 22.3 7.7

α = 0.1 4.5 2.7 2.4 5.2 15.5 6.0

β = 150 α = 0.5 4.5 2.7 2.4 5.2 15.5 6.0

α = 0.9 4.5 2.8 2.8 2.5 18.7 6.2

α = 0.1 5.0 3.2 3.1 5.2 15.8 6.4

β = 300 α = 0.5 5.0 3.2 3.1 5.2 20.8 7.4

α = 0.9 4.9 3.0 2.5 5.2 22.1 7.5

Table 3: Results obtained using different combinations of the α and β evaluation parameters. Relevant data includes the average number of generations required to attain full coverage.

4.3

Discussion

Automatic test case generation using search-based techniques is a difficult subject, especially if the aim is to implement an “universal” solution that is adaptable to a wide range of test objects. Key to the definition of a good strategy is the configuration of parameters so as to find a good balance between the intensification and the diversification of the search. With our approach, the test case evaluation parameters α and β and the evolutionary operators’ selection probabilities play a central role in the test case generation process. The main task of the mutation and crossover operators is that of diversifying the search, allowing it to browse through a wider area of the search landscape and to escape local maximums; the task of intensifying the search and guiding it towards the transversal of unexercised CFG nodes is performed as a result of the strategy of assigning weights to CFG nodes. Nevertheless, to strong a bias towards the breeding of feasible test cases will hinder the generation of more complex test cases, which are sometimes needed to exercise problem structures in the test object; on the other hand, if feasible test cases are not clearly encouraged, the search process will wander. This issue was addressed by allowing the fitness of feasible test cases to fluctuate throughout the search process as a result of the impact of the α and β parameters, in order to allow unfeasible test cases to be selected at certain points of the evolutionary search. The experiments performed allow drawing a preliminary conclusion: the assumption made on the Probabilities of Operators case study (Subsection 4.1), in which α = 0.9 was employed as being an adequate value, was wrong. Using lower values for this evaluation parameter yielded better results. On the other hand, it is possible to affirm that the strategy of assigning the value 150 to the unfeasible penalty constant

β yields good results. An explanation for this behaviour follows. The worst value a CFG node can have is 200 – since the weights of CFG nodes are normalized at the beginning of each generation (Equation 2). If all the nodes exercised by a feasible test case have the worst possible value – because they are being recurrently exercised by test cases, i.e., because the search is stuck in a local maximum – the fitness of the corresponding test case will also be 200 (Equation 3). However, for a given unfeasible test case t, if exIndt ≤ seqLent and β = 150, then F itnessunf easible (t) ∈ [150, 200] 2 – i.e., if the exception index of a given unfeasible test case is lower or equal to half of its MCS length, and if the value 150 is used for β, then the fitness of that test case will belong to the interval 150 to 200. This means that, with β = 150, some good unfeasible test cases may be selected for breeding; conversely, if β = 0, all unfeasible test cases will be evaluated with relatively good fitness values, and if β = 300, none of the unfeasible test cases will be evaluated as being interesting. The concept of good unfeasible test cases, in this context, can thus be verbalized as being a test case in which at least half of the MCS is executed without an exception being thrown. Assigning the value β = Winit − 50 is, thus, a good compromise between the need to penalize unfeasible test cases and the need to consider them at some points of the evolutionary search.

5.

CONCLUSIONS

Search-Based Test Case Generation is an emerging methodology for automatically generating high quality test data. However, the state problem of object-oriented programs requires the definition of carefully fine-tuned methodologies that promote the transversal of problematic structures and difficult control-flow paths, allowing both the exploration (diversification) and the exploitation (intensification) of the search space.

We proposed tackling this particular hindrance by defining weighted CFG nodes; their weight is dynamically reevaluated each generation, in order to cause the fitness of feasible test cases that exercise recurrently traversed structures to fluctuate throughout the search process. This strategy allows unfeasible test cases to be considered at certain points of the evolutionary search – once the feasible test cases that are being bred cease to be interesting. In conjunction with the impact of the evolutionary operators, a good compromise between the intensification and diversification of the search can be achieved. The strategy proposed was empirically evaluated with encouraging results.

6.

REFERENCES

[1] A. Arcuri and X. Yao. A memetic algorithm for test data generation of object-oriented software. In D. Srinivasan and L. Wang, editors, 2007 IEEE Congress on Evolutionary Computation, pages –, Singapore, 25-28 Sept. 2007. IEEE Computational Intelligence Society, IEEE Press. [2] A. Arcuri and X. Yao. Search based testing of containers for object-oriented software. Technical Report CSR-07-3, University of Birmingham, School of Computer Science, Apr. 2007. [3] S. Barbey and A. Strohmeier. The problematics of testing object-oriented software. In M. Ross, C. A. Brebbia, G. Staples, and J. Stapleton, editors, SQM’94 Second Conference on Software Quality Management, Edinburgh, Scotland, UK, July 26-28 1994, volume 2, pages 411–426, 1994. [4] Y. Cheon, M. Kim, and A. Perumandla. A complete automation of unit testing for java programs. In H. R. Arabnia and H. Reza, editors, Software Engineering Research and Practice, pages 290–295. CSREA Press, 2005. [5] M. Harman. The current state and future of search based software engineering. In FOSE ’07: 2007 Future of Software Engineering, pages 342–357, Washington, DC, USA, 2007. IEEE Computer Society. [6] A. Kinneer, M. Dwyer, and G. Rothermel. Sofya: A flexible framework for development of dynamic program analysis for java software. Technical Report TR-UNL-CSE-2006-0006, University of Nebraska, Lincoln, 4 2006. [7] J. R. Koza. Genetic Programming: On the Programming of Computers by Means of Natural Selection (Complex Adaptive Systems). The MIT Press, December 1992. [8] X. Liu, B. Wang, and H. Liu. Evolutionary search in the context of object-oriented programs. In MIC’05: Proceedings of the Sixth Metaheuristics International Conference, 2005. [9] S. Luke. ECJ 16: A Java evolutionary computation library. http://cs.gmu.edu/∼eclab/projects/ecj/, 2007. [10] T. Mantere and J. T. Alander. Evolutionary software engineering, a review. Appl. Soft Comput., 5(3):315–331, 2005. [11] P. McMinn. Search-based software test data generation: A survey. Software Testing, Verification and Reliability, 14(2):105–156, 2004. [12] P. McMinn and M. Holcombe. The state problem for evolutionary testing. In GECCO, pages 2488–2498,

2003. [13] D. J. Montana. Strongly typed genetic programming. Technical Report #7866, 10 Moulton Street, Cambridge, MA 02138, USA, 7 1993. [14] R. A. M¨ uller, C. Lembeck, and H. Kuchen. A symbolic java virtual machine for test case generation. In M. H. Hamza, editor, IASTED Conf. on Software Engineering, pages 365–371. IASTED/ACTA Press, 2004. [15] J. C. B. Ribeiro, F. F. de Vega, and M. Z. Rela. Using dynamic analysis of java bytecode for evolutionary object-oriented unit testing. In SBRC WTF 2007: Proceedings of the 8th Workshop on Testing and Fault Tolerance of the 25th Brazilian Symposium on Computer Networks and Distributed Systems, pages 143–156. Brazilian Computer Society (SBC), 2007. [16] J. C. B. Ribeiro, M. Zenha-Rela, and F. F. de Vega. ecrash: a framework for performing evolutionary testing on third-party java components. In JAEM CEDI 2007: Proceedings of the 1st Jornadas sobre Algoritmos Evolutivos y Metaheuristicas of the 2nd Congreso Espa˜ nol de Inform´ atica, pages 137–144, 2007. [17] J. C. B. Ribeiro, M. Zenha-Rela, and F. F. de Vega. An evolutionary approach for performing structural unit-testing on third-party object-oriented java software. In NICSO 2007: International Workshop on Nature Inspired Cooperative Strategies for Optimization (to appear), Studies in Computational Intelligence. Springer-Verlag, 11 2007. [18] R. Sagarna, A. Arcuri, and X. Yao. Estimation of distribution algorithms for testing object oriented software. In D. Srinivasan and L. Wang, editors, 2007 IEEE Congress on Evolutionary Computation, pages –, Singapore, 25-28 Sept. 2007. IEEE Computational Intelligence Society, IEEE Press. [19] A. Seesing and H.-G. GroSS. A genetic programming approach to automated test generation for object-oriented software. ITSSA, 1(2):127–134, 2006. [20] P. Tonella. Evolutionary testing of classes. In ISSTA ’04: Proceedings of the 2004 ACM SIGSOFT international symposium on Software testing and analysis, pages 119–128, New York, NY, USA, 2004. ACM Press. [21] S. Wappler and F. Lammermann. Using evolutionary algorithms for the unit testing of object-oriented software. In GECCO ’05: Proceedings of the 2005 conference on Genetic and evolutionary computation, pages 1053–1060, New York, NY, USA, 2005. ACM Press. [22] S. Wappler and J. Wegener. Evolutionary Unit Testing Of Object-Oriented Software Using A Hybrid Evolutionary Algorithm. In CEC’06: Proceedings of the 2006 IEEE Congress on Evolutionary Computation, pages 851–858. IEEE, 2006. [23] S. Wappler and J. Wegener. Evolutionary unit testing of object-oriented software using strongly-typed genetic programming. In GECCO ’06: Proceedings of the 8th annual conference on Genetic and evolutionary computation, pages 1925–1932, New York, NY, USA, 2006. ACM Press.

A Strategy for Evaluating Feasible and Unfeasible Test ...

May 11, 2008 - our on-going work is precisely on generating test data for the structural ...... Management, Edinburgh, Scotland, UK, July 26-28. 1994, volume 2 ...

335KB Sizes 0 Downloads 201 Views

Recommend Documents

A Strategy for Evaluating Feasible and Unfeasible Test ...
A Strategy for Evaluating Feasible and Unfeasible Test Cases for the Evolutionary Testing of Object-Oriented Software. A Strategy for Evaluating ... usually associated with the evolution of tree structures. ▻ It focuses on automatically ... Static

A Strategy for Evaluating Feasible and Unfeasible Test ...
May 11, 2008 - Permission to make digital or hard copies of all or part of this work for personal ... parameter types in the method signatures of the class under.

Evaluating Sources - The CRAAP Test
Key: ○ indicates criteria is for Web. C​urrency: ... Who is hosting or sponsoring the website? ... Does the language or tone seem unbiased and free of emotion?

Design and Implementation of a Combinatorial Test Suite Strategy ...
Design and Implementation of a Combinatorial Test Su ... rategy Using Adaptive Cuckoo Search Algorithm_ p.pdf. Design and Implementation of a ...

Developing a Framework for Evaluating Organizational Information ...
Mar 6, 2007 - Purpose, Mechanism, and Domain of Information Security . ...... Further, they argue that the free market will not force products and ...... Page 100 ...

Is a typology for planted forests feasible, or even relevant? - Center for ...
definition, and the fact that many terms are ideologically loaded. ... require mutually exclusive and jointly exhaustive categories, and are the focus of our analysis.

Evaluating a Website
On the supporting pages, is there a link back to the home page? Are the links clearly ... creator of the page, do you find additional information that shows the Web ...

PIRATES Test-Taking Strategy - Edgartown School
Step 1: Prepare to succeed. Put your name and PIRATES on the test. Allot time and order to sections. Say affirmations. Start within 2 minutes. Step 2: Inspect the ...

A Material Frame Approach for Evaluating Continuum ...
Nov 23, 2011 - directly from the momentum and energy balances using localization functions in a ... However, as technologies shrink to the nanometer range, quantities ..... 3 An alternate viewpoint considering only the transformation of ...

A Material Frame Approach for Evaluating Continuum ...
Nov 23, 2011 - This formulation relies on a mapping from reference to current .... atomic data to an Eulerian/spatial field ˜g(x,t) derived from the same ...... It can be seen that the agreement between P-K pressure and the virial remains excel-.

Evaluating a Private Management Agreement for ... - Rep. Seth Grove
Dec 12, 2012 - Contents. 1. Evaluating a Private Management Agreement for the PA Lottery. Process Timeline ... revenue to ensure the continued strength and viability of programs supporting a ... Aug. – Oct, 2012. PMA Business Terms and.

Draf paper A Methodology for Evaluating E-Learning ...
D. M. Cardona is student master in system engineer and computer science of the National .... other hand, audio/video streaming of lectures is usually useful.

A new method for evaluating forest thinning: growth ...
compared with cumulative growth (percentage of total) for each tree in that order. ..... Europe: data set. Available from ... Comprehensive database of diameter-based biomass re- gressions for ... Plant physiology: a big issue for trees. Nature.

A Markov Chain Model for Evaluating Seasonal Forest Fire Fighter ...
ABSTRACT. A model was developed to help resolve the decision of how many fire fighters a large forest fire management agency should hire for a fire season to minimize expected cost plus fire loss. It addresses the use of fire fighters for both initia

A new method for evaluating forest thinning: growth ...
treatments designed to reduce competition between trees and promote high ... However, this advantage may be offset by the countervailing physiological constraints imposed by large size, resulting in lower growth rates. ..... Europe: data set.

A strategy for sensitivity and specificity enhancements ...
cal activities. Sometimes .... mize the accessibility between the terminal groups of SAMs and the .... cal calibration curves obtained over the concentrations range.

A Business-Driven Framework for Evaluating Cloud ...
observed in the growth of mobile devices and Internet penetration ... It has also been used to compare the cost of hosting ..... using the cloud could reduce the NPV over $10k over ..... cle/352635/there best practice server system administrator.

Empath: A Framework for Evaluating Entity-Level ...
Singapore, 20060101, 20061231, 3.0 .... of entities in various domains, including businesses, com- ..... online news and its impact on british public attitudes.

A wavelet-based quality measure for evaluating the ...
In fact, without a. Further author information: (Send correspondence to Dr. Vladimir Buntilov) ... 6255, Fax: +66 (2) 889-2138 ext. 6268. ..... component PC1 of the decorrelated MS bands was replaced by its sharpened counterpart PC∗. 1 .

Evaluating a Private Management Agreement for ... - Rep. Seth Grove
Dec 12, 2012 - A Potential Solution: Private Management Agreement ... Oct, 2012. PMA Business Terms and .... Camelot was one of the U.K.'s “Top 100 Best.

Towards a Consistent Methodology for Evaluating ...
The Netherlands. Email: [email protected]. WWW home ... To address these issues, we propose to release a benchmark dataset which can be used to ...

A Strategy and Results Framework for the CGIAR
increases in other development investments— will make a big difference to ... developed the Strategy and Results Framework and the ―mega programs‖ (MPs) for ... and soil degradation (through improved land management practices, including ......