Skip to content

Commit

Permalink
Fail on number of surviving mutants
Browse files Browse the repository at this point in the history
  • Loading branch information
hcoles committed Apr 15, 2016
1 parent 8f654ad commit daf4844
Show file tree
Hide file tree
Showing 12 changed files with 258 additions and 348 deletions.
4 changes: 4 additions & 0 deletions pitest-ant/src/main/java/org/pitest/ant/PitestTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ public void setMutationThreshold(final String value) {
this.setOption(ConfigOption.MUTATION_THRESHOLD, value);
}

public void setMaxSurviving(final String value) {
this.setOption(ConfigOption.MAX_SURVIVING, value);
}

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

@Test
public void shouldPassMaxSurvivorsToJavaTask() {
this.pitestTask.setMaxSurviving("42");
this.pitestTask.execute(this.java);
verify(this.arg).setValue("--maxSurviving=42");
}

@Test
public void shouldPassCoverageThresholdToJavaTask() {
this.pitestTask.setCoverageThreshold("42");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public static void main(final String[] args) {
data.getCoverageThreshold());
throwErrorIfScoreBelowMutationThreshold(stats.getMutationStatistics(),
data.getMutationThreshold());
throwErrorIfMoreThanMaxSuvivingMutants(stats.getMutationStatistics(), data.getMaximumAllowedSurvivors());
}

}
Expand All @@ -69,6 +70,16 @@ private static void throwErrorIfScoreBelowMutationThreshold(
}
}

private static void throwErrorIfMoreThanMaxSuvivingMutants(
final MutationStatistics stats, final long threshold) {
if ((threshold > 0)
&& (stats.getTotalSurvivingMutations() > threshold)) {
throw new RuntimeException("Had "
+ stats.getTotalSurvivingMutations() + " surviving mutants, but only "
+ threshold + " survivors allowed");
}
}

private static CombinedStatistics runReport(ReportOptions data,
PluginServices plugins) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import static org.pitest.mutationtest.config.ConfigOption.INCLUDE_LAUNCH_CLASSPATH;
import static org.pitest.mutationtest.config.ConfigOption.JVM_PATH;
import static org.pitest.mutationtest.config.ConfigOption.MAX_MUTATIONS_PER_CLASS;
import static org.pitest.mutationtest.config.ConfigOption.MAX_SURVIVING;
import static org.pitest.mutationtest.config.ConfigOption.MUTATE_STATIC_INITIALIZERS;
import static org.pitest.mutationtest.config.ConfigOption.MUTATIONS;
import static org.pitest.mutationtest.config.ConfigOption.MUTATION_ENGINE;
Expand Down Expand Up @@ -107,6 +108,7 @@ public class OptionsParser {
private final ArgumentAcceptingOptionSpec<Boolean> detectInlinedCode;
private final ArgumentAcceptingOptionSpec<Integer> mutationThreshHoldSpec;
private final ArgumentAcceptingOptionSpec<Integer> coverageThreshHoldSpec;
private final ArgumentAcceptingOptionSpec<Integer> maxSurvivingSpec;
private final OptionSpec<String> mutationEngine;
private final ArgumentAcceptingOptionSpec<Boolean> exportLineCoverageSpec;
private final OptionSpec<String> javaExecutable;
Expand Down Expand Up @@ -279,6 +281,11 @@ public OptionsParser(Predicate<String> dependencyFilter) {
.withRequiredArg().ofType(Integer.class)
.describedAs("Mutation score below which to throw an error")
.defaultsTo(MUTATION_THRESHOLD.getDefault(Integer.class));

this.maxSurvivingSpec = parserAccepts(MAX_SURVIVING)
.withRequiredArg().ofType(Integer.class)
.describedAs("Maximum number of surviving mutants to allow without throwing an error")
.defaultsTo(MAX_SURVIVING.getDefault(Integer.class));

this.coverageThreshHoldSpec = parserAccepts(COVERAGE_THRESHOLD)
.withRequiredArg().ofType(Integer.class)
Expand Down Expand Up @@ -366,6 +373,7 @@ private ParseResult parseCommandLine(final ReportOptions data,
data.setHistoryInputLocation(this.historyInputSpec.value(userArgs));
data.setHistoryOutputLocation(this.historyOutputSpec.value(userArgs));
data.setMutationThreshold(this.mutationThreshHoldSpec.value(userArgs));
data.setMaximumAllowedSurvivors(this.maxSurvivingSpec.value(userArgs));
data.setCoverageThreshold(this.coverageThreshHoldSpec.value(userArgs));
data.setMutationEngine(this.mutationEngine.value(userArgs));
data.setFreeFormProperties(listToProperties(this.pluginPropertiesSpec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,13 @@ public void shouldParseMutationThreshold() {
"42");
assertEquals(42, actual.getMutationThreshold());
}

@Test
public void shouldParseMaximumAllowedSurvivingMutants() {
final ReportOptions actual = parseAddingRequiredArgs("--maxSurviving",
"42");
assertEquals(42, actual.getMaximumAllowedSurvivors());
}

@Test
public void shouldParseCoverageThreshold() {
Expand Down
17 changes: 17 additions & 0 deletions pitest-maven/src/main/java/org/pitest/maven/AbstractPitMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ public class AbstractPitMojo extends AbstractMojo {
@Parameter(defaultValue = "0", property = "mutationThreshold")
private int mutationThreshold;

/**
* Maximum surviving mutants to allow
*/
@Parameter(defaultValue = "-1", property = "maxSurviving")
private int maxSurviving;

/**
* Line coverage threshold at which to fail build
*/
Expand Down Expand Up @@ -336,6 +342,7 @@ public final void execute() throws MojoExecutionException,
final Option<CombinedStatistics> result = analyse();
if (result.hasSome()) {
throwErrorIfScoreBelowThreshold(result.value().getMutationStatistics());
throwErrorIfMoreThanMaximumSurvivors(result.value().getMutationStatistics());
throwErrorIfCoverageBelowThreshold(result.value().getCoverageSummary());
}

Expand Down Expand Up @@ -374,6 +381,16 @@ private void throwErrorIfScoreBelowThreshold(final MutationStatistics result)
+ this.mutationThreshold);
}
}

private void throwErrorIfMoreThanMaximumSurvivors(final MutationStatistics result)
throws MojoFailureException {
if ((this.maxSurviving > 0)
&& (result.getTotalSurvivingMutations() > this.maxSurviving)) {
throw new MojoFailureException("Had "
+ result.getTotalSurvivingMutations() + " surviving mutants, but only "
+ this.mutationThreshold + " survivors allowed");
}
}

protected Option<CombinedStatistics> analyse() throws MojoExecutionException {
final ReportOptions data = new MojoToReportOptionsConverter(this,
Expand Down
35 changes: 35 additions & 0 deletions pitest-maven/src/test/java/org/pitest/maven/PitMojoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,29 @@ public void testDoesNotThrowsMojoFailureExceptionWhenMutationScoreOnThreshold()
}
}

public void testThrowsMojoFailureExceptionWhenSurvivingMutantsAboveThreshold()
throws Exception {
this.testee = createPITMojo(createPomWithConfiguration("<maxSurviving>19</maxSurviving>"));
setupSuvivingMutants(20l);
try {
this.testee.execute();
fail();
} catch (final MojoFailureException ex) {
// pass
}
}

public void testDoesNotThrowsMojoFailureExceptionWhenSurvivingMutantsOnThreshold()
throws Exception {
this.testee = createPITMojo(createPomWithConfiguration("<maxSurviving>19</maxSurviving>"));
setupSuvivingMutants(19l);
try {
this.testee.execute();
} catch (final MojoFailureException ex) {
fail();
}
}

public void testThrowsMojoFailureExceptionWhenCoverageBelowThreshold()
throws Exception {
this.testee = createPITMojo(createPomWithConfiguration("<coverageThreshold>50</coverageThreshold>"));
Expand Down Expand Up @@ -123,6 +146,18 @@ private void setupCoverage(long mutationScore, int lines, int linesCovered)
any(ReportOptions.class), any(PluginServices.class), anyMap()))
.thenReturn(cs);
}

private void setupSuvivingMutants(long survivors)
throws MojoExecutionException {
final MutationStatistics stats = Mockito.mock(MutationStatistics.class);
when(stats.getTotalSurvivingMutations()).thenReturn(survivors);
CoverageSummary sum = new CoverageSummary(0, 0);
final CombinedStatistics cs = new CombinedStatistics(stats, sum);
when(
this.executionStrategy.execute(any(File.class),
any(ReportOptions.class), any(PluginServices.class), anyMap()))
.thenReturn(cs);
}

private Map<String, String> anyMap() {
return Matchers.<Map<String, String>> any();
Expand Down

0 comments on commit daf4844

Please sign in to comment.