Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Added the method pair coverage criterion from the EvoSuite tutorial.
  • Loading branch information
Gregory Gay committed Jun 6, 2016
1 parent 5c472d3 commit 5b92a32
Show file tree
Hide file tree
Showing 13 changed files with 568 additions and 2 deletions.
4 changes: 2 additions & 2 deletions client/src/main/java/org/evosuite/Properties.java
Expand Up @@ -591,7 +591,7 @@ public enum StoppingCondition {
public static StoppingCondition STOPPING_CONDITION = StoppingCondition.MAXTIME;

public enum CrossoverFunction {
SINGLEPOINTRELATIVE, SINGLEPOINTFIXED, SINGLEPOINT, COVERAGE
SINGLEPOINTRELATIVE, SINGLEPOINTFIXED, SINGLEPOINT, COVERAGE, MIDDLE
}

/** Constant <code>CROSSOVER_FUNCTION</code> */
Expand Down Expand Up @@ -1447,7 +1447,7 @@ public enum AlternativeFitnessCalculationMode {
public enum Criterion {
EXCEPTION, DEFUSE, ALLDEFS, BRANCH, CBRANCH, STRONGMUTATION, WEAKMUTATION,
MUTATION, STATEMENT, RHO, AMBIGUITY, IBRANCH, READABILITY,
ONLYBRANCH, ONLYMUTATION, METHODTRACE, METHOD, METHODNOEXCEPTION, LINE, ONLYLINE, OUTPUT, INPUT,
ONLYBRANCH, ONLYMUTATION, METHODTRACE, METHOD, METHODNOEXCEPTION, METHODPAIR, LINE, ONLYLINE, OUTPUT, INPUT,
REGRESSION, REGRESSIONTESTS, TRYCATCH
}

Expand Down
3 changes: 3 additions & 0 deletions client/src/main/java/org/evosuite/TestSuiteGenerator.java
Expand Up @@ -884,6 +884,9 @@ private void printTestCriterion(Criterion criterion) {
case METHODNOEXCEPTION:
LoggingUtils.getEvoLogger().info(" - No-Exception Top-Level Method Coverage");
break;
case METHODPAIR:
LoggingUtils.getEvoLogger().info(" - Method-Pair Coverage");
break;
case LINE:
LoggingUtils.getEvoLogger().info(" - Line Coverage");
break;
Expand Down
Expand Up @@ -166,6 +166,8 @@ public static RuntimeVariable getCoverageVariable(Properties.Criterion criterion
return RuntimeVariable.MethodCoverage;
case METHODNOEXCEPTION:
return RuntimeVariable.MethodNoExceptionCoverage;
case METHODPAIR:
//return RuntimeVariable.
case ONLYLINE:
case LINE:
return RuntimeVariable.LineCoverage;
Expand Down
Expand Up @@ -47,6 +47,8 @@
import org.evosuite.coverage.line.LineCoverageSuiteFitness;
import org.evosuite.coverage.line.OnlyLineCoverageSuiteFitness;
import org.evosuite.coverage.method.*;
import org.evosuite.coverage.methodpair.MethodPairCoverageFactory;
import org.evosuite.coverage.methodpair.MethodPairSuiteFitness;
import org.evosuite.coverage.mutation.*;
import org.evosuite.coverage.readability.ReadabilitySuiteFitness;
import org.evosuite.coverage.rho.RhoCoverageFactory;
Expand Down Expand Up @@ -117,6 +119,8 @@ public static TestSuiteFitnessFunction getFitnessFunction(Criterion criterion) {
return new MethodCoverageSuiteFitness();
case METHODNOEXCEPTION:
return new MethodNoExceptionCoverageSuiteFitness();
case METHODPAIR:
return new MethodPairSuiteFitness();
case ONLYLINE:
return new OnlyLineCoverageSuiteFitness();
case LINE:
Expand Down Expand Up @@ -179,6 +183,8 @@ public static TestFitnessFactory<? extends TestFitnessFunction> getFitnessFactor
return new MethodCoverageFactory();
case METHODNOEXCEPTION:
return new MethodNoExceptionCoverageFactory();
case METHODPAIR:
return new MethodPairCoverageFactory();
case LINE:
return new LineCoverageFactory();
case ONLYLINE:
Expand Down
@@ -0,0 +1,109 @@
/**
* Factory that assembles a list of pairs of method calls.
* Part of EvoSuite tutorial.
*
* @author Gregory Gay
* Copyright (C) 2010-2016 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
*/

package org.evosuite.coverage.methodpair;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.evosuite.Properties;
import org.evosuite.setup.TestUsageChecker;
import org.evosuite.testsuite.AbstractFitnessFactory;
import org.mockito.asm.Type;

public class MethodPairCoverageFactory extends AbstractFitnessFactory<MethodPairTestFitness> {

@Override
public List getCoverageGoals() {
List<MethodPairTestFitness> goals = new ArrayList<>();

String className = Properties.TARGET_CLASS;
Class<?> clazz = Properties.getInitializedTargetClass();
Set<String> constructors = getUsableConstructors(clazz);
Set<String> methods = getUsableMethods(clazz);


// Pair each constructor with each method and add to goals.
for(String constructor:constructors){
for(String method: methods){
goals.add(new MethodPairTestFitness(className, constructor, method));
}
}

// Pair each method with each other method and add to goals.
for(String method1: methods){
for(String method2: methods){
goals.add(new MethodPairTestFitness(className,method1,method2));
}
}

return goals;
}

/**
* Returns a list of constructors in the correct format (name + descriptor).
* Uses reflection to get a list of constructors declared by CUT.
* For each, produces name and descriptor.
* @param clazz - class under test
* @return set of constructors
*/
protected Set<String> getUsableConstructors(Class<?> clazz){
Set<String> constructors = new LinkedHashSet<>();

Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
for(Constructor<?> c: allConstructors){
if(TestUsageChecker.canUse(c)){
String methodName = "<init>"+Type.getConstructorDescriptor(c);
constructors.add(methodName);
}
}

return constructors;
}

/**
* Returns a list of methods in the correct format (name + descriptor).
* Uses reflection to get a list of methods declared by CUT.
* For each, produces name and descriptor.
* @param clazz - class under test
* @return set of constructors
*/
protected Set<String> getUsableMethods(Class<?> clazz){
Set<String> methods = new LinkedHashSet<>();

Method[] allMethods = clazz.getDeclaredMethods();
for(Method m: allMethods){
if(TestUsageChecker.canUse(m)){
String methodName = m.getName()+Type.getMethodDescriptor(m);
methods.add(methodName);
}
}

return methods;
}
}
@@ -0,0 +1,87 @@
/**
* New fitness function, based on pairs of method calls.
* Part of EvoSuite tutorial.
*
* @author Gregory Gay
* Copyright (C) 2010-2016 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
*/

package org.evosuite.coverage.methodpair;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.evosuite.testcase.ExecutableChromosome;
import org.evosuite.testcase.execution.ExecutionResult;
import org.evosuite.testsuite.AbstractTestSuiteChromosome;
import org.evosuite.testsuite.TestSuiteFitnessFunction;

public class MethodPairSuiteFitness extends TestSuiteFitnessFunction {

// Track the method pairs.
private final Set<MethodPairTestFitness> allMethodPairs = new HashSet<>();

public MethodPairSuiteFitness(){
// Get method pairs from the fitness factory.
allMethodPairs.addAll(new MethodPairCoverageFactory().getCoverageGoals());
}

@Override
public double getFitness(AbstractTestSuiteChromosome<? extends ExecutableChromosome> individual) {
double fitness = 0.0;

// Run all tests and gather the execution results.
List<ExecutionResult> results = runTestSuite(individual);
Set<MethodPairTestFitness> coveredMethodPairs = new HashSet<>();

// Go through and look for covered goals.
for(MethodPairTestFitness goal: allMethodPairs){
for(ExecutionResult result: results){
if(goal.isCovered(result)){
coveredMethodPairs.add(goal);
break;
}
}
}

// Fitness is the total number of goals - the number of covered goals.
// If all goals are covered, fitness will be 0.
fitness = allMethodPairs.size() - coveredMethodPairs.size();

// Penalize fitness if the test suite times out.
for (ExecutionResult result : results) {
if (result.hasTimeout() || result.hasTestException()) {
fitness = allMethodPairs.size();
break;
}
}

// Update the fitness score for the suite.
updateIndividual(this, individual, fitness);
individual.setNumOfCoveredGoals(this, coveredMethodPairs.size());
if(!allMethodPairs.isEmpty()){
individual.setCoverage(this, (double) coveredMethodPairs.size() / (double) allMethodPairs.size());
}else{
individual.setCoverage(this, 1.0);
}
return fitness;
}

}

0 comments on commit 5b92a32

Please sign in to comment.