Skip to content

Commit

Permalink
Feat: junit5 pit (#70)
Browse files Browse the repository at this point in the history
* pom: add dependency to pitest junit 5

* feat: configure the test plugin correctly when running junit5

* test: add a manual test for pit on junit 5

* refactor: remove old commenteed code
  • Loading branch information
danglotb authored May 2, 2019
1 parent 54611da commit 35674c8
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 48 deletions.
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.3.2</version>
<version>1.2.0</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -161,6 +161,12 @@
<version>3.0.0</version>
</dependency>

<dependency>
<groupId>org.pitest</groupId>
<artifactId>pitest-junit5-plugin</artifactId>
<version>0.8</version>
</dependency>

</dependencies>

<build>
Expand Down
67 changes: 45 additions & 22 deletions src/main/java/eu/stamp_project/testrunner/EntryPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
import eu.stamp_project.testrunner.utils.ConstantsHelper;
import org.apache.commons.io.FileUtils;
import org.jacoco.core.runtime.IRuntime;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.objectweb.asm.xml.Processor;
import org.opentest4j.TestAbortedException;
import org.pitest.junit5.JUnit5Configuration;
import org.pitest.mutationtest.config.PluginServices;
import org.pitest.mutationtest.engine.gregor.GregorMutationEngine;
import org.pitest.testapi.TestGroupConfig;
Expand Down Expand Up @@ -302,7 +305,7 @@ public static Coverage runCoverage(String classpath, String targetProjectClasses
EntryPoint.blackList.isEmpty() ? "" :
(ParserOptions.FLAG_blackList + ConstantsHelper.WHITE_SPACE
+ String.join(ConstantsHelper.PATH_SEPARATOR, EntryPoint.blackList)),
});
});
return EntryPoint.runCoverage(javaCommand);
}

Expand Down Expand Up @@ -376,17 +379,17 @@ public static CoveragePerTestMethod runCoveragePerTestMethods(String classpath,
final String javaCommand = String.join(ConstantsHelper.WHITE_SPACE,
new String[]{
getJavaCommand(),
classpath + ConstantsHelper.PATH_SEPARATOR + ABSOLUTE_PATH_TO_RUNNER_CLASSES
+ ConstantsHelper.PATH_SEPARATOR + ABSOLUTE_PATH_TO_JACOCO_DEPENDENCIES,
EntryPoint.jUnit5Mode ? EntryPoint.JUNIT5_JACOCO_RUNNER_PER_TEST_QUALIFIED_NAME : EntryPoint.JUNIT4_JACOCO_RUNNER_PER_TEST_QUALIFIED_NAME,
ParserOptions.FLAG_pathToCompiledClassesOfTheProject,
targetProjectClasses, ParserOptions.FLAG_fullQualifiedNameOfTestClassToRun,
String.join(ConstantsHelper.PATH_SEPARATOR, fullQualifiedNameOfTestClasses),
methodNames.length == 0 ? "" : ParserOptions.FLAG_testMethodNamesToRun + ConstantsHelper.WHITE_SPACE +
String.join(ConstantsHelper.PATH_SEPARATOR, methodNames),
EntryPoint.blackList.isEmpty() ? ""
: (ParserOptions.FLAG_blackList + ConstantsHelper.WHITE_SPACE
+ String.join(ConstantsHelper.PATH_SEPARATOR, EntryPoint.blackList)),
classpath + ConstantsHelper.PATH_SEPARATOR + ABSOLUTE_PATH_TO_RUNNER_CLASSES
+ ConstantsHelper.PATH_SEPARATOR + ABSOLUTE_PATH_TO_JACOCO_DEPENDENCIES,
EntryPoint.jUnit5Mode ? EntryPoint.JUNIT5_JACOCO_RUNNER_PER_TEST_QUALIFIED_NAME : EntryPoint.JUNIT4_JACOCO_RUNNER_PER_TEST_QUALIFIED_NAME,
ParserOptions.FLAG_pathToCompiledClassesOfTheProject,
targetProjectClasses, ParserOptions.FLAG_fullQualifiedNameOfTestClassToRun,
String.join(ConstantsHelper.PATH_SEPARATOR, fullQualifiedNameOfTestClasses),
methodNames.length == 0 ? "" : ParserOptions.FLAG_testMethodNamesToRun + ConstantsHelper.WHITE_SPACE +
String.join(ConstantsHelper.PATH_SEPARATOR, methodNames),
EntryPoint.blackList.isEmpty() ? ""
: (ParserOptions.FLAG_blackList + ConstantsHelper.WHITE_SPACE
+ String.join(ConstantsHelper.PATH_SEPARATOR, EntryPoint.blackList)),
});
try {
EntryPoint.runGivenCommandLine(javaCommand);
Expand Down Expand Up @@ -415,14 +418,26 @@ public static List<? extends AbstractPitResult> runPit(final String classpath,
final String pathToRootProject,
final String filterTargetClasses,
final String targetTests) {
final String classpathToExecute;
if (jUnit5Mode) {
classpathToExecute = String.join(ConstantsHelper.PATH_SEPARATOR,
new String[]{
classpath,
ABSOLUTE_PATH_TO_PIT_DEPENDENCIES,
ABSOLUTE_PATH_TO_PIT_DEPENDENCIES_FOR_JUNIT5
}
);
} else {
classpathToExecute = String.join(ConstantsHelper.PATH_SEPARATOR,
new String[]{
classpath,
ABSOLUTE_PATH_TO_PIT_DEPENDENCIES
}
);
}
PitRunner.main(
new String[]{
String.join(ConstantsHelper.PATH_SEPARATOR,
new String[]{
classpath,
ABSOLUTE_PATH_TO_PIT_DEPENDENCIES
}
),
classpathToExecute,
pathToRootProject,
filterTargetClasses,
targetTests,
Expand Down Expand Up @@ -566,10 +581,9 @@ private static String RemoveWinFileSeparator(String string) {
.map(clazz -> clazz.getProtectionDomain().getCodeSource().getLocation()).map(URL::getPath)
.map(path -> path.startsWith("file:") ? path.substring("file:".length()) : path)
.map(path -> path.split("!")[0]).map(path -> path.replace("/", ConstantsHelper.FILE_SEPARATOR))
.map(EntryPoint::RemoveWinFileSeparator).map(path -> {
LOGGER.info("{}", path);
return path;
}).collect(Collectors.joining(ConstantsHelper.PATH_SEPARATOR));
.map(EntryPoint::RemoveWinFileSeparator)
.peek(path -> LOGGER.info("{}", path))
.collect(Collectors.joining(ConstantsHelper.PATH_SEPARATOR));

private static final List<Class<?>> JACOCO_DEPENDENCIES = Arrays.asList(IRuntime.class, Processor.class,
FileUtils.class);
Expand All @@ -584,9 +598,18 @@ private static String RemoveWinFileSeparator(String string) {
DescartesMutationEngine.class
);

private static final List<Class<?>> PIT_DEPENDENCIES_FOR_JUNIT5 = Arrays.asList(
JUnit5Configuration.class,
ExtensionContext.class,
TestAbortedException.class
);

private static final String ABSOLUTE_PATH_TO_PIT_DEPENDENCIES = CLASSES_TO_PATH_OF_DEPENDENCIES
.apply(PIT_DEPENDENCIES);

private static final String ABSOLUTE_PATH_TO_PIT_DEPENDENCIES_FOR_JUNIT5 = CLASSES_TO_PATH_OF_DEPENDENCIES
.apply(PIT_DEPENDENCIES_FOR_JUNIT5);

private static String initAbsolutePathToRunnerClasses() {
URL resource = ClassLoader.getSystemClassLoader().getResource("runner-classes/");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ public enum State {SURVIVED, KILLED, NO_COVERAGE, TIMED_OUT, NON_VIABLE, MEMORY_

protected final String simpleNameMethod;

// protected CtMethod testCase = null;

public AbstractPitResult(String fullQualifiedNameOfMutatedClass, AbstractPitResult.State stateOfMutant,
String fullQualifiedNameMutantOperator,
String fullQualifiedNameMethod, String fullQualifiedNameOfKiller,
Expand Down Expand Up @@ -56,25 +54,11 @@ public String getFullQualifiedNameOfKiller() {
return fullQualifiedNameOfKiller;
}

// TODO move this somewhere in DSpot...
/*
public CtMethod getMethod(CtType<?> ctClass) {
if ("none".equals(this.simpleNameMethod)) {
return null;
} else {
if (this.testCase == null) {
List<CtMethod<?>> methodsByName = ctClass.getMethodsByName(this.simpleNameMethod);
if (methodsByName.isEmpty()) {
if (ctClass.getSuperclass() != null) {
return getMethod(ctClass.getSuperclass().getDeclaration());
} else {
return null;
}
}
this.testCase = methodsByName.get(0);
}
return this.testCase;
}
public String getFullQualifiedNameOfMutatedClass() {
return fullQualifiedNameOfMutatedClass;
}

public String getSimpleNameMethod() {
return simpleNameMethod;
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public String toString() {
", stateOfMutant=" + stateOfMutant +
", fullQualifiedNameOfKiller='" + fullQualifiedNameOfKiller + '\'' +
", simpleNameMethod='" + simpleNameMethod + '\'' +
// ", testCase=" + testCase +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ public String toString() {
", stateOfMutant=" + stateOfMutant +
", fullQualifiedNameOfKiller='" + fullQualifiedNameOfKiller + '\'' +
", simpleNameMethod='" + simpleNameMethod + '\'' +
// ", testCase=" + testCase + '\'' +
", methodDescription='" + methodDescription + '\'' +
", mutationDescription='" + mutationDescription + '\'' +
", index='" + index + '\'' +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.pitest.mutationtest.config.SettingsFactory;
import org.pitest.mutationtest.tooling.EntryPoint;
import org.pitest.testapi.TestGroupConfig;
import org.pitest.util.Glob;

import java.io.File;
import java.net.URL;
Expand All @@ -23,6 +22,10 @@
*/
public class PitRunner {

private static final String JUNIT4_TEST_PLUGIN = "junit";

private static final String JUNIT5_TEST_PLUGIN = "junit5";

public final static String REPORT_PITS = "target/report-pits/";

/**
Expand Down Expand Up @@ -85,6 +88,11 @@ private static ReportOptions createReportOptions(final String classpath,
data.setGroupConfig(testGroupConfig);
data.setExportLineCoverage(true);
data.setMutationEngine(mutationEngine);
data.setTestPlugin(
eu.stamp_project.testrunner.EntryPoint.jUnit5Mode ?
JUNIT5_TEST_PLUGIN :
JUNIT4_TEST_PLUGIN
);
return data;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
import eu.stamp_project.testrunner.listener.Coverage;
import eu.stamp_project.testrunner.listener.CoveragePerTestMethod;
import eu.stamp_project.testrunner.listener.TestResult;
import eu.stamp_project.testrunner.listener.pit.AbstractPitResult;
import eu.stamp_project.testrunner.runner.Failure;
import eu.stamp_project.testrunner.utils.ConstantsHelper;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.jupiter.api.extension.ExtensionContext;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;
import java.util.concurrent.TimeoutException;

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
Expand All @@ -37,6 +41,27 @@ public void tearDown() throws Exception {
EntryPoint.jUnit5Mode = false;
}

@Ignore
@Test
public void testPitRun() throws TimeoutException {

/*
Run pit with default option on test projects.
Default options are using descartes mutation engine and default mutators of descartes.
This result with a list of pit result.
NOTE: it seems that running pit in debug mode (in IDEA) does not work, be careful.
*/

final List<? extends AbstractPitResult> pitResults = EntryPoint.runPit(
JUNIT_CP + ConstantsHelper.PATH_SEPARATOR + TEST_PROJECT_CLASSES,
"src/test/resources/test-projects/",
"example.*",
"junit5.TestSuiteExample"
);
assertEquals(2, pitResults.size());
assertEquals(2, pitResults.stream().filter(result -> result.getStateOfMutant() == AbstractPitResult.State.KILLED).count());
}

@Ignore
@Test
public void testWithBlackList() throws Exception {
Expand Down

0 comments on commit 35674c8

Please sign in to comment.