Skip to content

Commit

Permalink
Doc(prettifier): instructions & configuration options (#950)
Browse files Browse the repository at this point in the history
  • Loading branch information
lacinoire authored Jun 10, 2020
1 parent 3d9be16 commit 78e59c6
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 31 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,9 @@ Please, do not amplify test classes that mix test frameworks (test methods in JU

If you have such test class, please amplify the different test framework separately.

## Minimizing and Prettifying DSpot Amplified Test Cases
With the [DSpot Prettifier](dspot-prettifier) you can remove redundant assertions from your amplified test cases & give them more expressive names with the help of code2vec and context2vec.

## Contributing

DSpot is licensed under LGPLv3. Contributors and pull requests are welcome :-).
Expand Down
23 changes: 23 additions & 0 deletions dspot-prettifier/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,29 @@ The process has 3 steps:
2. Rename the test method. This is done using [code2vec](https://github.com/tech-srl/code2vec).
3. Rename the local variable used in the the test method. This is done based on [context2name](https://github.com/rbavishi/Context2Name).

## Command Line Usage
```
java -jar /path/to/dspot-prettifier-LATEST-jar-with-dependencies.jar --apply-all-prettifiers --absolute-path-to-project-root=<path> --path-to-amplified-test-class=<path>
```

The prettifier uses DSpot in the background, you can pass all arguments that you can also pass to DSpot.

### Configure Prettifiers
To select which prettifiers should be applied to the amplified test case you can pass these options:
```
--apply-all-prettifiers
Apply all available prettifiers. This overrides options that turn off specific
prettifiers. Default value: false
--apply-general-minimizer
Apply the general minimizer to remove redundant assertions and inline local variables.
Default value: false
--apply-pit-minimizer Apply the pit minimizer to remove assertions that do not improve the mutation score.
Default value: false
--rename-local-variables
Apply Context2Vec to give the local variables more expressive names. Default value: false
--rename-test-methods Apply Code2Vec to give the test methods more expressive names. Default value: false
```

## Install
For __code2vec__, you need to run `install_code2vec.sh` to download repo.

Expand Down
2 changes: 1 addition & 1 deletion dspot-prettifier/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
</descriptorRefs>
<archive>
<manifest>
<mainClass>eu.stamp_project.prettifier.code2vec.builder.Main</mainClass>
<mainClass>eu.stamp_project.prettifier.Main</mainClass>
</manifest>
</archive>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,30 @@ public static List<CtMethod<?>> run(CtType<?> amplifiedTestClass,

final List<CtMethod<?>> testMethods = TestFramework.getAllTest(amplifiedTestClass);
Main.report.nbTestMethods = testMethods.size();
final List<CtMethod<?>> minimizedAmplifiedTestMethods;

// 1 minimize amplified test methods
final List<CtMethod<?>> minimizedAmplifiedTestMethods = applyMinimization(
testMethods,
amplifiedTestClass,
configuration
);
if (configuration.isApplyAllPrettifiers() || configuration.isApplyGeneralMinimizer() || configuration.isApplyPitMinimizer()) {
minimizedAmplifiedTestMethods = applyMinimization(
testMethods,
amplifiedTestClass,
configuration
);
} else {
minimizedAmplifiedTestMethods = testMethods;
}
// 2 rename test methods
applyCode2Vec(minimizedAmplifiedTestMethods, configuration);
// 3 Rename local variables TODO train one better model
return applyContext2Name(minimizedAmplifiedTestMethods);
if (configuration.isApplyAllPrettifiers() || configuration.isRenameTestMethods()) {
applyCode2Vec(minimizedAmplifiedTestMethods, configuration);
}
// 3 rename local variables TODO train one better model
final List<CtMethod<?>> prettifiedTestMethods;
if (configuration.isApplyAllPrettifiers() || configuration.isRenameLocalVariables()) {
prettifiedTestMethods = applyContext2Name(minimizedAmplifiedTestMethods);
} else {
prettifiedTestMethods = minimizedAmplifiedTestMethods;
}
return prettifiedTestMethods;
}

public static List<CtMethod<?>> applyMinimization(List<CtMethod<?>> amplifiedTestMethodsToBeMinimized,
Expand All @@ -134,27 +148,31 @@ public static List<CtMethod<?>> applyMinimization(List<CtMethod<?>> amplifiedTes
.map(List::size)
.collect(Collectors.toList()));

// 1rst apply a general minimization
amplifiedTestMethodsToBeMinimized = Main.applyGivenMinimizer(new GeneralMinimizer(), amplifiedTestMethodsToBeMinimized);
// update the test class with minimized test methods
final ArrayList<CtMethod<?>> allMethods = new ArrayList<>(amplifiedTestClass.getMethods());
allMethods.stream()
.filter(TestFramework.get()::isTest)
.forEach(amplifiedTestClass::removeMethod);
amplifiedTestMethodsToBeMinimized.forEach(amplifiedTestClass::addMethod);
// 1 apply general minimization
if (configuration.isApplyAllPrettifiers() || configuration.isApplyGeneralMinimizer()) {
amplifiedTestMethodsToBeMinimized = Main.applyGivenMinimizer(new GeneralMinimizer(), amplifiedTestMethodsToBeMinimized);
// update the test class with minimized test methods
final ArrayList<CtMethod<?>> allMethods = new ArrayList<>(amplifiedTestClass.getMethods());
allMethods.stream()
.filter(TestFramework.get()::isTest)
.forEach(amplifiedTestClass::removeMethod);
amplifiedTestMethodsToBeMinimized.forEach(amplifiedTestClass::addMethod);
}

final AutomaticBuilder automaticBuilder = configuration.getBuilderEnum().getAutomaticBuilder(configuration);
// 2nd apply a specific minimization
amplifiedTestMethodsToBeMinimized = Main.applyGivenMinimizer(
new PitMutantMinimizer(
amplifiedTestClass,
automaticBuilder,
configuration.getAbsolutePathToProjectRoot(),
configuration.getClasspathClassesProject(),
configuration.getAbsolutePathToTestClasses()
),
amplifiedTestMethodsToBeMinimized
);
// 2 apply pit minimization
if (configuration.isApplyAllPrettifiers() || configuration.isApplyPitMinimizer()) {
final AutomaticBuilder automaticBuilder = configuration.getBuilderEnum().getAutomaticBuilder(configuration);
amplifiedTestMethodsToBeMinimized = Main.applyGivenMinimizer(
new PitMutantMinimizer(
amplifiedTestClass,
automaticBuilder,
configuration.getAbsolutePathToProjectRoot(),
configuration.getClasspathClassesProject(),
configuration.getAbsolutePathToTestClasses()
),
amplifiedTestMethodsToBeMinimized
);
}

Main.report.medianNbStatementAfter = Main.getMedian(amplifiedTestMethodsToBeMinimized.stream()
.map(ctMethod -> ctMethod.getElements(new TypeFilter<>(CtStatement.class)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,93 @@ public UserInput setPathToAmplifiedTestClass(String pathToAmplifiedTestClass) {
return this;
}

// which Prettifiers to apply

@CommandLine.Option(
names = "--apply-all-prettifiers",
description = "Apply all available prettifiers. This overrides options that turn off specific prettifiers." +
" Default value: ${DEFAULT-VALUE}",
defaultValue = "false"
)
private boolean applyAllPrettifiers;

public boolean isApplyAllPrettifiers() {
return applyAllPrettifiers;
}

public UserInput setApplyAllPrettifiers(boolean applyAllPrettifiers) {
this.applyAllPrettifiers = applyAllPrettifiers;
return this;
}

@CommandLine.Option(
names = "--apply-general-minimizer",
description = "Apply the general minimizer to remove redundant assertions and inline local variables." +
" Default value: ${DEFAULT-VALUE}",
defaultValue = "false"
)
private boolean applyGeneralMinimizer;

public boolean isApplyGeneralMinimizer() {
return applyGeneralMinimizer;
}

public UserInput setApplyGeneralMinimizer(boolean applyGeneralMinimizer) {
this.applyGeneralMinimizer = applyGeneralMinimizer;
return this;
}

@CommandLine.Option(
names = "--apply-pit-minimizer",
description = "Apply the pit minimizer to remove assertions that do not improve the mutation score." +
" Default value: ${DEFAULT-VALUE}",
defaultValue = "false"
)
private boolean applyPitMinimizer;

public boolean isApplyPitMinimizer() {
return applyPitMinimizer;
}

public UserInput setApplyPitMinimizer(boolean applyPitMinimizer) {
this.applyPitMinimizer = applyPitMinimizer;
return this;
}

@CommandLine.Option(
names = "--rename-test-methods",
description = "Apply Code2Vec to give the test methods more expressive names." +
" Default value: ${DEFAULT-VALUE}",
defaultValue = "false"
)
private boolean renameTestMethods;

public boolean isRenameTestMethods() {
return renameTestMethods;
}

public UserInput setRenameTestMethods(boolean renameTestMethods) {
this.renameTestMethods = renameTestMethods;
return this;
}

@CommandLine.Option(
names = "--rename-local-variables",
description = "Apply Context2Vec to give the local variables more expressive names." +
" Default value: ${DEFAULT-VALUE}",
defaultValue = "false"
)
private boolean renameLocalVariables;

public boolean isRenameLocalVariables() {
return renameLocalVariables;
}

public UserInput setRenameLocalVariables(boolean renameLocalVariables) {
this.renameLocalVariables = renameLocalVariables;
return this;
}

// Code2Vec

@CommandLine.Option(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/
public abstract class AbstractTest {

public String getPathToPropertiesFile() {
public String getAbsolutePathToProjectRoot() {
return "src/test/resources/sample/";
}

Expand All @@ -25,7 +25,7 @@ public void setUp() throws Exception {
RandomHelper.setSeedRandom(72L);
ValueCreator.count = 0;
this.configuration = new UserInput();
this.configuration.setAbsolutePathToProjectRoot(this.getPathToPropertiesFile());
this.configuration.setAbsolutePathToProjectRoot(this.getAbsolutePathToProjectRoot());
this.configuration.setVerbose(true);
this.configuration.setBuilderEnum(AutomaticBuilderEnum.Maven);
this.configuration.setGregorMode(true);
Expand Down
89 changes: 89 additions & 0 deletions dspot-prettifier/src/test/java/eu/stamp_project/MainTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package eu.stamp_project;

import eu.stamp_project.prettifier.Main;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import java.io.File;

import static org.junit.Assert.assertTrue;

public class MainTest {

@Before
public void setUp() throws Exception {
try {
FileUtils.deleteDirectory(new File("target/dspot/output/"));
FileUtils.deleteDirectory(new File("src/test/resources/sample/target"));
} catch (Exception ignored) {

}
}

@After
public void tearDown() throws Exception {
try {
FileUtils.deleteDirectory(new File("target/dspot/output/"));
FileUtils.deleteDirectory(new File("src/test/resources/sample/target"));
} catch (Exception ignored) {

}
}

@Test
public void testNoPrettifiers() throws Exception {
Main.main(new String[]{
"--absolute-path-to-project-root", "src/test/resources/sample/",
"--path-to-amplified-test-class", "src/test/resources/sample/src/test/java/fr/inria/amplified/AmplifiedTest.java"
});
assertTrue(new File("target/dspot/output/fr/inria/amplified/AmplifiedTest.java").exists());
}

@Test
public void testApplyGeneralMinimizer() throws Exception {
Main.main(new String[]{
"--absolute-path-to-project-root", "src/test/resources/sample/",
"--path-to-amplified-test-class", "src/test/resources/sample/src/test/java/fr/inria/amplified/AmplifiedTest.java",
"--apply-general-minimizer"
});
assertTrue(new File("target/dspot/output/fr/inria/amplified/AmplifiedTest.java").exists());
}

@Test
public void testApplyPitMinimizer() throws Exception {
Main.main(new String[]{
"--absolute-path-to-project-root", "src/test/resources/sample/",
"--path-to-amplified-test-class", "src/test/resources/sample/src/test/java/fr/inria/amplified/AmplifiedTest.java",
"--apply-pit-minimizer"
});
assertTrue(new File("target/dspot/output/fr/inria/amplified/AmplifiedTest.java").exists());
}

@Ignore // DOES NOT WORK ON TRAVIS, CANNOT FIND python3 cmd
@Test
public void testRenameTestMethods() throws Exception {
Main.main(new String[]{
"--absolute-path-to-project-root", "src/test/resources/sample/",
"--path-to-amplified-test-class", "src/test/resources/sample/src/test/java/fr/inria/amplified/AmplifiedTest.java",
"--path-to-code2vec", "src/test/resources/code2vec/code2vec",
"--path-to-code2vec-model", "../model",
"--rename-test-methods"
});
assertTrue(new File("target/dspot/output/fr/inria/amplified/AmplifiedTest.java").exists());
}

@Test
public void testRenameLocalVariables() throws Exception {
Main.main(new String[]{
"--absolute-path-to-project-root", "src/test/resources/sample/",
"--path-to-amplified-test-class", "src/test/resources/sample/src/test/java/fr/inria/amplified/AmplifiedTest.java",
"--path-to-code2vec", "src/test/resources/code2vec/code2vec",
"--path-to-code2vec-model", "../model",
"--rename-local-variables"
});
assertTrue(new File("target/dspot/output/fr/inria/amplified/AmplifiedTest.java").exists());
}
}

0 comments on commit 78e59c6

Please sign in to comment.