Skip to content

Commit

Permalink
Merge pull request #1040 from hcoles/feature/junit5_style_discovery
Browse files Browse the repository at this point in the history
Speed up JUnit 5 coverage but supporting single phase test discovery/execution
  • Loading branch information
hcoles committed Jun 22, 2022
2 parents ae8c498 + 4875ec7 commit 98b9f64
Show file tree
Hide file tree
Showing 56 changed files with 389 additions and 1,145 deletions.
4 changes: 0 additions & 4 deletions pitest-ant/src/main/java/org/pitest/ant/PitestTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,6 @@ public void setTargetTests(final String value) {
this.setOption(ConfigOption.TEST_FILTER, value);
}

public void setDependencyDistance(final String value) {
this.setOption(ConfigOption.DEPENDENCY_DISTANCE, value);
}

public void setThreads(final String value) {
this.setOption(ConfigOption.THREADS, value);
}
Expand Down
7 changes: 0 additions & 7 deletions pitest-ant/src/test/java/org/pitest/ant/PitestTaskTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,6 @@ public void shouldPassAvoidCallsOptionToJavaTask() {
verify(this.arg).setValue("--avoidCallsTo=avoidCalls");
}

@Test
public void shouldPassDependencyDistanceOptionToJavaTask() {
this.pitestTask.setDependencyDistance("distance");
this.pitestTask.execute(this.java);
verify(this.arg).setValue("--dependencyDistance=distance");
}

@Test
public void shouldPassExcludedClassesOptionToJavaTask() {
this.pitestTask.setExcludedClasses("String");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
import static org.pitest.mutationtest.config.ConfigOption.CLASSPATH_FILE;
import static org.pitest.mutationtest.config.ConfigOption.CODE_PATHS;
import static org.pitest.mutationtest.config.ConfigOption.COVERAGE_THRESHOLD;
import static org.pitest.mutationtest.config.ConfigOption.DEPENDENCY_DISTANCE;
import static org.pitest.mutationtest.config.ConfigOption.EXCLUDED_CLASSES;
import static org.pitest.mutationtest.config.ConfigOption.EXCLUDED_GROUPS;
import static org.pitest.mutationtest.config.ConfigOption.EXCLUDED_METHOD;
Expand Down Expand Up @@ -102,7 +101,6 @@ public class OptionsParser {
private final OptionSpec<String> targetClassesSpec;
private final OptionSpec<String> targetTestsSpec;
private final OptionSpec<String> avoidCallsSpec;
private final OptionSpec<Integer> depth;
private final OptionSpec<Integer> threadsSpec;
private final OptionSpec<File> sourceDirSpec;
private final OptionSpec<File> historyOutputSpec;
Expand Down Expand Up @@ -184,11 +182,6 @@ public OptionsParser(Predicate<String> dependencyFilter) {
.describedAs(
"comma separated list of filters to match against tests to run");

this.depth = parserAccepts(DEPENDENCY_DISTANCE).withRequiredArg()
.ofType(Integer.class)
.defaultsTo(DEPENDENCY_DISTANCE.getDefault(Integer.class))
.describedAs("maximum distance to look from test for covered classes");

this.threadsSpec = parserAccepts(THREADS).withRequiredArg()
.ofType(Integer.class).defaultsTo(THREADS.getDefault(Integer.class))
.describedAs("number of threads to use for testing");
Expand Down Expand Up @@ -422,7 +415,7 @@ private ParseResult parseCommandLine(final ReportOptions data,
data.setSourceDirs(this.sourceDirSpec.values(userArgs));
data.setMutators(this.mutators.values(userArgs));
data.setFeatures(this.features.values(userArgs));
data.setDependencyAnalysisMaxDistance(this.depth.value(userArgs));

data.addChildJVMArgs(this.jvmArgsProcessor.values(userArgs));

data.setFullMutationMatrix(this.fullMutationMatrixSpec.value(userArgs));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,6 @@ public void shouldParseCommaSeparatedListOfSourceDirectories() {
assertEquals(Arrays.asList(new File("foo/bar"), new File("bar/far")), actual.getSourceDirs());
}

@Test
public void shouldParseMaxDepenencyDistance() {
final ReportOptions actual = parseAddingRequiredArgs(
"--dependencyDistance", "42");
assertEquals(42, actual.getDependencyAnalysisMaxDistance());
}

@Test
public void shouldParseCommaSeparatedListOfJVMArgs() {
final ReportOptions actual = parseAddingRequiredArgs("--jvmArgs", "foo,bar");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ public ClassPath getClassPath() {
return this.classPath.getClassPath();
}

public ProjectClassPaths getProjectPaths() {
return this.classPath;
}

public Optional<ClassName> findTestee(final String className) {
final TestToClassMapper mapper = new TestToClassMapper(this.classRepository);
return mapper.findTestee(className);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ private void checkForFailedTest(final CoverageResult cr) {

private TestInfo createTestInfo(final Description description,
final int executionTime, final int linesCovered) {

if (description.getFirstTestClass() == null) {
System.out.println(description);
}

final Optional<ClassName> testee = this.code.findTestee(description
.getFirstTestClass());
return new TestInfo(description.getFirstTestClass(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ public class CoverageProcess {

public CoverageProcess(final ProcessArgs processArgs,
final CoverageOptions arguments, final ServerSocket socket,
final List<String> testClases, final Consumer<CoverageResult> handler)
throws IOException {
final List<String> testClases, final Consumer<CoverageResult> handler) {
this.process = new WrappingProcess(socket.getLocalPort(), processArgs,
CoverageMinion.class);
this.crt = new CoverageCommunicationThread(socket, arguments, testClases,
Expand All @@ -30,7 +29,7 @@ public void start() throws IOException, InterruptedException {
this.process.start();
}

public ExitCode waitToDie() throws InterruptedException {
public ExitCode waitToDie() {
try {
return this.crt.waitToFinish();
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ public enum ConfigOption {
* Features to enable/disable
*/
FEATURES("features"),
/**
* Maximum number of hops from a mutable class to a test
*/
DEPENDENCY_DISTANCE("dependencyDistance", -1),

/**
* Arguments to launch child processes with
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ public class ReportOptions {
private Collection<String> mutators;
private Collection<String> features;

private int dependencyAnalysisMaxDistance;

private final List<String> jvmArgs = new ArrayList<>(DEFAULT_CHILD_JVM_ARGS);
private int numberOfThreads = 0;
private float timeoutFactor = PercentAndConstantTimeoutStrategy.DEFAULT_FACTOR;
Expand Down Expand Up @@ -213,22 +211,6 @@ public void setFeatures(Collection<String> features) {
this.features = features;
}

/**
* @return the dependencyAnalysisMaxDistance
*/
public int getDependencyAnalysisMaxDistance() {
return this.dependencyAnalysisMaxDistance;
}

/**
* @param dependencyAnalysisMaxDistance
* the dependencyAnalysisMaxDistance to set
*/
public void setDependencyAnalysisMaxDistance(
final int dependencyAnalysisMaxDistance) {
this.dependencyAnalysisMaxDistance = dependencyAnalysisMaxDistance;
}

public List<String> getJvmArgs() {
return this.jvmArgs;
}
Expand Down Expand Up @@ -661,7 +643,6 @@ public String toString() {
.add("classPathElements=" + classPathElements)
.add("mutators=" + mutators)
.add("features=" + features)
.add("dependencyAnalysisMaxDistance=" + dependencyAnalysisMaxDistance)
.add("jvmArgs=" + jvmArgs)
.add("numberOfThreads=" + numberOfThreads)
.add("timeoutFactor=" + timeoutFactor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ public TestPrioritiserFactory getTestPrioritiser() {
public CoverageOptions createCoverageOptions() {
return new CoverageOptions(
this.options.getTargetClasses(), this.options.getExcludedClasses(),
this.options.createMinionSettings(), this.options.getVerbosity(),
this.options.getDependencyAnalysisMaxDistance());
this.options.createMinionSettings(), this.options.getVerbosity());
}

public CompoundInterceptorFactory getInterceptor() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.coverage.execute.samples.executionindiscovery;

public class ATesteeClass {

public String foo(int i) {
if (i > 10) {
return "fuzz";
}
return "bizz";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.coverage.execute.samples.executionindiscovery;

import org.pitest.executingtest.ExecutingTest;

import static org.assertj.core.api.Assertions.assertThat;

public class AnExecutingTest {
@ExecutingTest
public void aTest() {
ATesteeClass a = new ATesteeClass();
assertThat(a.foo(1)).isEqualTo("bizz");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.example.coverage.execute.samples.exceptions.ThrowsExceptionFromLargeMethodTestee;
import com.example.coverage.execute.samples.exceptions.ThrowsExceptionInFinallyBlockTestee;
import com.example.coverage.execute.samples.exceptions.ThrowsExceptionTestee;
import com.example.coverage.execute.samples.executionindiscovery.AnExecutingTest;
import com.example.coverage.execute.samples.simple.ParentChildInitializationTest;
import com.example.coverage.execute.samples.simple.Testee;
import com.example.coverage.execute.samples.simple.Testee2;
Expand All @@ -31,7 +32,6 @@
import org.pitest.util.SocketFinder;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
Expand All @@ -42,7 +42,6 @@
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -243,7 +242,7 @@ public void testNewLine() throws IOException {
}

@Test
public void shouldNotCorruptedTheSystemNewLineProperty() throws Exception {
public void shouldNotCorruptTheSystemNewLineProperty() throws Exception {
final List<CoverageResult> coveredClasses = runCoverageForTest(ReliesOnNewLineTest.class);
assertThat(coveredClasses).noneMatch(failingTest());
}
Expand All @@ -255,13 +254,11 @@ public void handlesParentChildInitializationOrderIssues() throws Exception {
.anyMatch(coverageFor(ClassName.fromString("com.example.coverage.execute.samples.simple.TesteeChild")));
}

private ClassPath classPathWithoutJUnit() {
final List<File> cpWithoutJUnit =
ClassPath.getClassPathElementsAsFiles().stream()
.filter(file -> !file.getName().contains("junit"))
.collect(Collectors.toList());

return new ClassPath(cpWithoutJUnit);
@Test
public void gathersCoverageWhenTestsExecutedDuringDiscovery() throws Exception {
final List<CoverageResult> coveredClasses = runCoverageForTest(AnExecutingTest.class);
assertThat(coveredClasses)
.anyMatch(coverageFor(ClassName.fromString("com.example.coverage.execute.samples.executionindiscovery.ATesteeClass")));
}

private Predicate<CoverageResult> failingTest() {
Expand All @@ -282,7 +279,7 @@ private void runCoverageProcess(final Class<?> test,
InterruptedException {
final Consumer<CoverageResult> handler = a -> coveredClasses.add(a);

final CoverageOptions sa = new CoverageOptions(coverOnlyTestees(), excludeTests(), TestPluginArguments.defaults(), VERBOSE, -1);
final CoverageOptions sa = new CoverageOptions(coverOnlyTestees(), excludeTests(), TestPluginArguments.defaults(), VERBOSE);

final JarCreatingJarFinder agent = new JarCreatingJarFinder();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,6 @@ public void shouldPickRelevantTestsAndKillMutationsBasedOnCoverageData() {
verifyResults(KILLED);
}

@Test
public void shouldPickRelevantTestsAndKillMutationsBasedOnCoverageDataWhenLimitedByClassReach() {
this.data.setDependencyAnalysisMaxDistance(2);
this.data.setTargetTests(predicateFor("com.example.*FullyCovered*"));
this.data.setTargetClasses(asList("com.example.FullyCovered*"));
createAndRun();
verifyResults(KILLED);
}

@Test
public void shouldReportUnCoveredMutations() {
this.data.setTargetClasses(asList("com.example.PartiallyCovered*"));
Expand Down Expand Up @@ -254,7 +245,6 @@ public void shouldMutateClassesSuppliedToAlternateClassPath()
cp.add(location);

this.data.setClassPathElements(cp);
this.data.setDependencyAnalysisMaxDistance(-1);
this.data.setExcludedClasses(asList("*Power*", "*JMockit*"));
createAndRun();
verifyResults(KILLED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,7 @@ code, this.data, new SettingsFactory(this.data, this.plugins),

private CoverageOptions createCoverageOptions(TestPluginArguments configuration) {
return new CoverageOptions(this.data.getTargetClasses(),this.data.getExcludedClasses(),
configuration, this.data.getVerbosity(),
this.data.getDependencyAnalysisMaxDistance());
configuration, this.data.getVerbosity());
}

protected void setMutators(final String mutator) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ private void run(final Class<?> clazz, final Class<?> test,

final Set<Predicate<String>> tests = Collections.singleton(isEqual(test.getName()));
data.setTargetTests(tests);
data.setDependencyAnalysisMaxDistance(-1);

final Set<String> mutees = Collections.singleton(clazz.getName() + "*");
data.setTargetClasses(mutees);
Expand Down Expand Up @@ -295,7 +294,7 @@ null, coverageOptions, launchOptions, code, new NullCoverageExporter(),

private CoverageOptions createCoverageOptions(ReportOptions data) {
return new CoverageOptions(data.getTargetClasses(),data.getExcludedClasses(), this.config,
data.getVerbosity(), data.getDependencyAnalysisMaxDistance());
data.getVerbosity());
}

protected void verifyResults(final DetectionStatus... detectionStatus) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public void shouldProduceConsistantCoverageData() throws Exception {
}

@Test
@Ignore
// debatable if this test should be here. Relies on external testng plugin
public void shouldWorkWithTestNG() throws Exception {
File testDir = prepare("/pit-testng");
Expand Down Expand Up @@ -394,6 +395,7 @@ public void shouldWorkWithYatspec() throws Exception {
}

@Test
@Ignore
// note this test depends on the junit5 plugin
public void shouldWorkWithQuarkus() throws Exception {
assumeTrue(CurrentRuntime.version() >= 11);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private ReportOptions parseReportOptions(final List<String> classPath) {

data.setUseClasspathJar(this.mojo.isUseClasspathJar());
data.setClassPathElements(classPath);
data.setDependencyAnalysisMaxDistance(this.mojo.getMaxDependencyDistance());

data.setFailWhenNoMutations(shouldFailWhenNoMutations());

data.setTargetClasses(determineTargetClasses());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,6 @@ public void testUsesSourceDirectoriesFromProject() {
actual.getSourceDirs());
}

public void testParsesMaxDependencyDistance() {
final ReportOptions actual = parseConfig("<maxDependencyDistance>42</maxDependencyDistance>");
assertEquals(42, actual.getDependencyAnalysisMaxDistance());
}

public void testParsesExcludedRunners() {
String runner = "org.springframework.test.context.junit4.SpringJUnit4ClassRunner";
final ReportOptions actual = parseConfig("<excludedRunners><param>" + runner + "</param></excludedRunners>");
Expand Down
Loading

0 comments on commit 98b9f64

Please sign in to comment.