Skip to content

Commit

Permalink
Fix #537 keep original test method (#585)
Browse files Browse the repository at this point in the history
* test: AmplificationHelper should not keep original test methods if the option is not enabled

* feat: add an option to keep or not the original test methods

* refactor: update API of InputConfiguration

* doc: update README

* feat: add the new option to the maven plugin

* fix: add instead of remove original test method

* fix: keep original tests and generate new test class
  • Loading branch information
danglotb authored Oct 17, 2018
1 parent ee95de4 commit 2c49006
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 36 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,15 @@ java -jar /path/to/dspot-LATEST-jar-with-dependencies.jar --path-to-properties d

```
Usage: java -jar target/dspot-<version>-jar-with-dependencies.jar
[(-p|--path-to-properties) <./path/to/myproject.properties>] [(-a|--amplifiers) Amplifier1:Amplifier2:...:AmplifierN ] [(-i|--iteration) <iteration>] [(-s|--test-criterion) <PitMutantScoreSelector | ExecutedMutantSelector | CloverCoverageSelector | JacocoCoverageSelector | TakeAllSelector | ChangeDetectorSelector>] [--budgetizer <NoBudgetizer | SimpleBuddgetizer>] [--max-test-amplified <integer>] [(-t|--test) my.package.MyClassTest | all | diff1:my.package.MyClassTest | all | diff2:...:my.package.MyClassTest | all | diffN ] [(-c|--cases) testCases1:testCases2:...:testCasesN ] [(-o|--output-path) <output>] [--clean] [(-m|--path-pit-result) <./path/to/mutations.csv>] [--descartes] [--automatic-builder <MavenBuilder | GradleBuilder>] [--maven-home <path to maven home>] [--randomSeed <long integer>] [--timeOut <long integer>] [--verbose] [--with-comment] [--no-minimize] [--working-directory] [-e|--example] [-h|--help]
[(-p|--path-to-properties) <./path/to/myproject.properties>] [(-a|--amplifiers) Amplifier1:Amplifier2:...:AmplifierN ] [(-i|--iteration) <iteration>] [(-s|--test-criterion) <PitMutantScoreSelector | ExecutedMutantSelector | CloverCoverageSelector | JacocoCoverageSelector | TakeAllSelector | ChangeDetectorSelector>] [--budgetizer <NoBudgetizer | SimpleBudgetizer>] [--max-test-amplified <integer>] [(-t|--test) my.package.MyClassTest | all | diff1:my.package.MyClassTest | all | diff2:...:my.package.MyClassTest | all | diffN ] [(-c|--cases) testCases1:testCases2:...:testCasesN ] [(-o|--output-path) <output>] [--clean] [(-m|--path-pit-result) <./path/to/mutations.csv>] [--descartes] [--automatic-builder <MavenBuilder | GradleBuilder>] [--maven-home <path to maven home>] [--randomSeed <long integer>] [--timeOut <long integer>] [--verbose] [--with-comment] [--no-minimize] [--working-directory] [--generate-new-test-class] [--keep-original-test-methods] [--use-maven-to-exe-test] [-e|--example] [-h|--help]
[(-p|--path-to-properties) <./path/to/myproject.properties>]
[mandatory] specify the path to the configuration file (format Java
properties) of the target project (e.g. ./foo.properties).
[(-a|--amplifiers) Amplifier1:Amplifier2:...:AmplifierN ]
[optional] specify the list of amplifiers to use. Default with all
available amplifiers.
available amplifiers.
- StringLiteralAmplifier
- NumberLiteralAmplifier
- CharLiteralAmplifier
Expand All @@ -207,7 +207,7 @@ Usage: java -jar target/dspot-<version>-jar-with-dependencies.jar
[optional] specify the test adequacy criterion to be maximized with
amplification (default: PitMutantScoreSelector)
[--budgetizer <NoBudgetizer | SimpleBuddgetizer>]
[--budgetizer <NoBudgetizer | SimpleBudgetizer>]
[optional] specify a Bugdetizer. (default: NoBudgetizer)
[--max-test-amplified <integer>]
Expand Down Expand Up @@ -243,7 +243,7 @@ Usage: java -jar target/dspot-<version>-jar-with-dependencies.jar
[--automatic-builder <MavenBuilder | GradleBuilder>]
[optional] specify the automatic builder to build the project (default:
MavenBuilder)
)
[--maven-home <path to maven home>]
specify the path to the maven home
Expand Down Expand Up @@ -271,7 +271,11 @@ Usage: java -jar target/dspot-<version>-jar-with-dependencies.jar
[--generate-new-test-class]
Enable the creation of a new test class.
[--keep-original-test-methods]
If enabled, DSpot keeps original test methods of the amplified test
class.
[--use-maven-to-exe-test]
If enabled, DSpot will use maven to execute the tests.
Expand Down
9 changes: 9 additions & 0 deletions dspot-maven/src/main/java/eu/stamp_project/DSpotMojo.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package eu.stamp_project;

import eu.stamp_project.options.AmplifierEnum;
import eu.stamp_project.options.BudgetizerEnum;
import eu.stamp_project.options.JSAPOptions;
import eu.stamp_project.options.SelectorEnum;
import eu.stamp_project.program.ConstantsProperties;
Expand Down Expand Up @@ -169,6 +170,12 @@ public class DSpotMojo extends AbstractMojo {
@Parameter(defaultValue = "false", property = "generate-new-test-class")
private Boolean generateNewTestClass;

/**
* If enabled, DSpot keeps original test methods of the amplified test class.
*/
@Parameter(defaultValue = "false", property = "keep-original-test-methods")
private Boolean keepOriginalTestMethods;

/**
* If enabled, DSpot will use maven to execute the tests.
*/
Expand Down Expand Up @@ -225,6 +232,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
.setNbIteration(this.iteration)
.setTestClasses(this.test)
.setSelector(SelectorEnum.valueOf(this.testCriterion).buildSelector())
.setBudgetizer(BudgetizerEnum.valueOf(this.budgetizer).getBugtizer())
.setTestCases(this.cases)
.setSeed(this.randomSeed)
.setTimeOutInMs(this.timeOut)
Expand All @@ -237,6 +245,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
.setWithComment(this.withComment)
.setDescartesMode(this.descartes)
.setGenerateAmplifiedTestClass(this.generateNewTestClass)
.setKeepOriginalTestMethods(this.keepOriginalTestMethods)
.setOutputDirectory(this.outputPath)
.setUseMavenToExecuteTest(this.useMavenToExeTest);

Expand Down
7 changes: 7 additions & 0 deletions dspot/src/main/java/eu/stamp_project/options/JSAPOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public static InputConfiguration parse(String[] args) {
.setUseWorkingDirectory(jsapConfig.getBoolean("working-directory"))
.setWithComment(jsapConfig.getBoolean("comment"))
.setGenerateAmplifiedTestClass(jsapConfig.getBoolean("generate-new-test-class"))
.setKeepOriginalTestMethods(jsapConfig.getBoolean("keep-original-test-methods"))
.setDescartesMode(jsapConfig.getBoolean("descartes"))
.setUseMavenToExecuteTest(jsapConfig.getBoolean("use-maven-to-exe-test"));
}
Expand Down Expand Up @@ -250,6 +251,11 @@ private static JSAP initJSAP() {
generateNewTestClass.setDefault("false");
generateNewTestClass.setHelp("Enable the creation of a new test class.");

Switch keepOriginalTestMethods = new Switch("keep-original-test-methods");
keepOriginalTestMethods.setLongFlag("keep-original-test-methods");
keepOriginalTestMethods.setDefault("false");
keepOriginalTestMethods.setHelp("If enabled, DSpot keeps original test methods of the amplified test class.");

Switch useMavenToExecuteTests = new Switch("use-maven-to-exe-test");
useMavenToExecuteTests.setLongFlag("use-maven-to-exe-test");
useMavenToExecuteTests.setDefault("false");
Expand Down Expand Up @@ -277,6 +283,7 @@ private static JSAP initJSAP() {
jsap.registerParameter(nominimize);
jsap.registerParameter(useWorkingDirectory);
jsap.registerParameter(generateNewTestClass);
jsap.registerParameter(keepOriginalTestMethods);
jsap.registerParameter(useMavenToExecuteTests);
jsap.registerParameter(example);
jsap.registerParameter(help);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,7 @@ public InputConfiguration setBudgetizer(Budgetizer budgetizer) {
* This new test class will be named with "Ampl" as suffix or prefix depending of the name of the original test class:
* <i>e.g.</i> MyClassTest will be AmplMyClassTest and TestMyClass will be TestMyClassAmpl
*/
public boolean isGenerateAmplifiedTestClass() {
public boolean shouldGenerateAmplifiedTestClass() {
return generateAmplifiedTestClass;
}

Expand All @@ -909,12 +909,26 @@ public InputConfiguration setGenerateAmplifiedTestClass(boolean generateAmplifie
*/
private boolean useMavenToExecuteTest = false;

public boolean isUseMavenToExecuteTest() {
public boolean shouldUseMavenToExecuteTest() {
return useMavenToExecuteTest;
}

public InputConfiguration setUseMavenToExecuteTest(boolean useMavenToExecuteTest) {
this.useMavenToExecuteTest = useMavenToExecuteTest;
return this;
}

/**
* This boolean say if the outputs test class should also contain original test methods.
*/
private boolean keepOriginalTestMethods = false;

public boolean shouldKeepOriginalTestMethods() {
return this.keepOriginalTestMethods;
}

public InputConfiguration setKeepOriginalTestMethods(boolean keepOriginalTestMethods) {
this.keepOriginalTestMethods = keepOriginalTestMethods;
return this;
}
}
32 changes: 18 additions & 14 deletions dspot/src/main/java/eu/stamp_project/utils/AmplificationHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,28 +65,35 @@ public static void reset() {
@SuppressWarnings("unchecked")
public static CtType<?> createAmplifiedTest(List<CtMethod<?>> ampTest, CtType<?> classTest) {
final Stream<CtMethod<?>> methodToAdd;
// TODO minimize
if (InputConfiguration.get().shouldMinimize()) {
final Minimizer minimizer = InputConfiguration.get().getSelector().getMinimizer();
methodToAdd = ampTest.stream().map(minimizer::minimize);
} else {
methodToAdd = ampTest.stream();
}
if (InputConfiguration.get().isGenerateAmplifiedTestClass()) {
CtType amplifiedTest = classTest.clone();
final CtType<?> currentTestClass = classTest.clone();
methodToAdd.forEach(currentTestClass::addMethod);
// keep original test methods
if (!InputConfiguration.get().shouldKeepOriginalTestMethods()) {
classTest.getMethods().stream()
.filter(AmplificationChecker::isTest)
.forEach(currentTestClass::removeMethod);
}
// generate a new test class
if (InputConfiguration.get().shouldGenerateAmplifiedTestClass()) {
final String amplifiedName = getAmplifiedName(classTest);
amplifiedTest.setSimpleName(amplifiedName);
classTest.getMethods().stream().filter(AmplificationChecker::isTest).forEach(amplifiedTest::removeMethod);
methodToAdd.forEach(amplifiedTest::addMethod);
currentTestClass.setSimpleName(amplifiedName);
final CtTypeReference classTestReference = classTest.getReference();
// renaming all the Spoon nodes
amplifiedTest.getElements(new TypeFilter<CtTypeReference>(CtTypeReference.class) {
currentTestClass.getElements(new TypeFilter<CtTypeReference>(CtTypeReference.class) {
@Override
public boolean matches(CtTypeReference element) {
return element.equals(classTestReference) && super.matches(element);
return element.equals(classTestReference);
}
}).forEach(ctTypeReference -> ctTypeReference.setSimpleName(getAmplifiedName(classTest)));
}).forEach(ctTypeReference -> ctTypeReference.setSimpleName(amplifiedName));
// need to update also all the String literals
amplifiedTest.getElements(new TypeFilter<CtLiteral>(CtLiteral.class) {
currentTestClass.getElements(new TypeFilter<CtLiteral>(CtLiteral.class) {
@Override
public boolean matches(CtLiteral element) {
return element.getValue() instanceof String &&
Expand All @@ -95,12 +102,9 @@ public boolean matches(CtLiteral element) {
}).forEach(stringCtLiteral ->
stringCtLiteral.setValue(((String)stringCtLiteral.getValue()).replaceAll(classTest.getSimpleName(), amplifiedName))
);
classTest.getPackage().addType(amplifiedTest);
return amplifiedTest;
} else {
methodToAdd.forEach(classTest::addMethod);
return classTest;
}
classTest.getPackage().addType(currentTestClass);
return currentTestClass;
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public static TestListener runGivenTestMethods(CtType<?> testClass, List<CtMetho
}

public static TestListener run(String classpath, String rootPath, String fullQualifiedName, String... testToRun) throws TimeoutException {
if (InputConfiguration.get().isUseMavenToExecuteTest()) {
if (InputConfiguration.get().shouldUseMavenToExecuteTest()) {
return eu.stamp_project.testrunner.maven.EntryPoint.runTests(
rootPath,
fullQualifiedName,
Expand Down
1 change: 1 addition & 0 deletions dspot/src/test/java/eu/stamp_project/AbstractTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ public void setUp() throws Exception {
Utils.getInputConfiguration().setVerbose(true);
Utils.getInputConfiguration().setMinimize(false);
InputConfiguration.get().setGenerateAmplifiedTestClass(false);
InputConfiguration.get().setKeepOriginalTestMethods(false);
}
}
16 changes: 9 additions & 7 deletions dspot/src/test/java/eu/stamp_project/MainTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ public void testOverrideExistingResults() throws Exception {
/*
Test that we can append result in different runs of DSpot, or not, according to the --clean (-q) flag
Here, we run 4 time DSpot.
- 1 time with a lot of Amplifiers: result with a lof of amplified test
- then we if append result of run 2 and run 3, we obtain the same result than the 1
- 1 time with a lot of Amplifiers: result with a lot of amplified test
- then we append result of run 2 and run 3, we obtain the same result than the 1
- the fourth is the same of the third time, but not appended to the result of the second
*/

Expand All @@ -193,11 +193,11 @@ public void testOverrideExistingResults() throws Exception {
"--amplifiers", "MethodAdd" + AmplificationHelper.PATH_SEPARATOR + "TestDataMutator" + AmplificationHelper.PATH_SEPARATOR + "MethodGeneratorAmplifier" + AmplificationHelper.PATH_SEPARATOR + "ReturnValueAmplifier",
"--iteration", "1",
"--randomSeed", "72",
//"--maven-home", DSpotUtils.buildMavenHome(new InputConfiguration("src/test/resources/test-projects/test-projects.properties")),
"--test", "example.TestSuiteExample",
"--cases", "test2",
"--output-path", "target/trash",
"--max-test-amplified", "200"
"--max-test-amplified", "200",
"--keep-original-test-methods"
});
Launcher launcher = new Launcher();
launcher.getEnvironment().setNoClasspath(true);
Expand All @@ -212,11 +212,11 @@ public void testOverrideExistingResults() throws Exception {
"--amplifiers", "MethodAdd" + AmplificationHelper.PATH_SEPARATOR + "TestDataMutator",
"--iteration", "1",
"--randomSeed", "72",
//"--maven-home", DSpotUtils.buildMavenHome(new InputConfiguration("src/test/resources/test-projects/test-projects.properties")),
"--test", "example.TestSuiteExample",
"--cases", "test2",
"--output-path", "target/trash",
"--max-test-amplified", "200",
"--keep-original-test-methods",
"--clean"
});
launcher = new Launcher();
Expand All @@ -234,29 +234,31 @@ public void testOverrideExistingResults() throws Exception {
"--amplifiers", "MethodGeneratorAmplifier" + AmplificationHelper.PATH_SEPARATOR + "ReturnValueAmplifier",
"--iteration", "1",
"--randomSeed", "72",
//"--maven-home", DSpotUtils.buildMavenHome(new InputConfiguration("src/test/resources/test-projects/test-projects.properties")),
"--test", "example.TestSuiteExample",
"--cases", "test2",
"--output-path", "target/trash",
"--max-test-amplified", "200",
"--keep-original-test-methods"
});
launcher = new Launcher();
launcher.getEnvironment().setNoClasspath(true);
launcher.getEnvironment().setAutoImports(true);
launcher.addInputResource("target/trash/example/TestSuiteExample.java");
launcher.buildModel();
final CtClass<?> testClass3 = launcher.getFactory().Class().get("example.TestSuiteExample");

//
Main.main(new String[]{
"--path-to-properties", "src/test/resources/test-projects/test-projects.properties",
"--test-criterion", "JacocoCoverageSelector",
"--amplifiers", "MethodGeneratorAmplifier" + AmplificationHelper.PATH_SEPARATOR + "ReturnValueAmplifier",
"--iteration", "1",
"--randomSeed", "72",
//"--maven-home", DSpotUtils.buildMavenHome(new InputConfiguration("src/test/resources/test-projects/test-projects.properties")),
"--test", "example.TestSuiteExample",
"--cases", "test2",
"--output-path", "target/trash",
"--max-test-amplified", "200",
"--keep-original-test-methods",
"--clean"
});
launcher = new Launcher();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public void test() throws Exception {
/*
Test the whole dspot procedure.
*/

InputConfiguration.get().setKeepOriginalTestMethods(true);

ValueCreator.count = 0;
RandomHelper.setSeedRandom(23L);
final InputConfiguration configuration = InputConfiguration.get();
Expand Down
Loading

0 comments on commit 2c49006

Please sign in to comment.