Skip to content

Commit 088524f

Browse files
authored
Merge pull request #69 from carmeloquilez/feature/addTestStrengthMetric
Feature/add test strength metric
2 parents e454452 + f0da64b commit 088524f

File tree

5 files changed

+65
-14
lines changed

5 files changed

+65
-14
lines changed

pom.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<artifactId>mutation-analysis-plugin</artifactId>
2525
<groupId>ch.devcon5.sonar</groupId>
2626
<packaging>sonar-plugin</packaging>
27-
<version>1.6</version>
27+
<version>1.7</version>
2828

2929
<name>${project.artifactId}</name>
3030
<description>Sonar Plugin for integrating and visualizing mutation analysis results</description>
@@ -79,6 +79,7 @@
7979
<license.title>Mutation Analysis Plugin</license.title>
8080
<license.years>2015-2021</license.years>
8181
<license.mailto>info@devcon5.ch</license.mailto>
82+
<sonarQubeMinVersion>7.9.5</sonarQubeMinVersion>
8283
</properties>
8384

8485
<dependencies>
@@ -166,6 +167,7 @@
166167
<pluginKey>mutationanalysis</pluginKey>
167168
<pluginClass>ch.devcon5.sonar.plugins.mutationanalysis.MutationAnalysisPlugin</pluginClass>
168169
<pluginName>Mutation Analysis</pluginName>
170+
<sonarQubeMinVersion>${sonarQubeMinVersion}</sonarQubeMinVersion>
169171
</configuration>
170172
</plugin>
171173

src/main/java/ch/devcon5/sonar/plugins/mutationanalysis/metrics/MutationMetrics.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,17 @@ private MutationMetrics(){}
118118
.setDecimalScale(1)
119119
.create();
120120

121+
public static final String MUTATIONS_TEST_STRENGTH_KEY = "dc5_mutationAnalysis_mutations_test_strength";
122+
public static final Metric<Serializable> MUTATIONS_TEST_STRENGTH = new Metric.Builder(MUTATIONS_TEST_STRENGTH_KEY, "Test Strength", Metric.ValueType.PERCENT)
123+
.setDirection(DIRECTION_BETTER)
124+
.setDomain(MUTATION_ANALYSIS_DOMAIN)
125+
.setQualitative(true)
126+
.setDescription("Test strength percentage")
127+
.setBestValue(100.)
128+
.setWorstValue(0.)
129+
.setDecimalScale(1)
130+
.create();
131+
121132
public static final String MUTATIONS_DENSITY_KEY = "dc5_mutationAnalysis_mutations_density";
122133
public static final Metric<Serializable> MUTATIONS_DENSITY=new Metric.Builder(MUTATIONS_DENSITY_KEY, "Mutation: Density", Metric.ValueType.PERCENT)
123134
.setDirection(DIRECTION_WORST)
@@ -224,6 +235,7 @@ private MutationMetrics(){}
224235
MUTATIONS_DATA,
225236
MUTATIONS_TOTAL_PERCENT,
226237
MUTATIONS_COVERAGE,
238+
MUTATIONS_TEST_STRENGTH,
227239
MUTATIONS_DENSITY,
228240
MUTATIONS_ALIVE_PERCENT,
229241
TEST_KILL_RATIO

src/main/java/ch/devcon5/sonar/plugins/mutationanalysis/metrics/MutationScoreComputer.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ public MutationScoreComputer(final Configuration config) {
4646
public MeasureComputerDefinition define(final MeasureComputerDefinitionContext defContext) {
4747

4848
return defContext.newDefinitionBuilder()
49-
.setInputMetrics(MutationMetrics.MUTATIONS_DETECTED.key(), MutationMetrics.MUTATIONS_TOTAL.key())
50-
.setOutputMetrics(MutationMetrics.MUTATIONS_COVERAGE.key())
49+
.setInputMetrics(MutationMetrics.MUTATIONS_DETECTED.key(), MutationMetrics.MUTATIONS_TOTAL.key(), MutationMetrics.MUTATIONS_SURVIVED.key())
50+
.setOutputMetrics(MutationMetrics.MUTATIONS_COVERAGE.key(), MutationMetrics.MUTATIONS_TEST_STRENGTH.key())
5151
.build();
5252
}
5353

@@ -69,12 +69,30 @@ public void compute(final MeasureComputerContext context) {
6969
final Double coverage = 100.0 * coveredElements / elements;
7070
LOG.info("Computed Mutation Coverage of {}% for {}", coverage, context.getComponent());
7171
context.addMeasure(MutationMetrics.MUTATIONS_COVERAGE.key(), coverage);
72+
73+
final Measure aliveMutantsMeasure = context.getMeasure(MutationMetrics.MUTATIONS_SURVIVED.key());
74+
int aliveMutants = aliveMutantsMeasure != null ? aliveMutantsMeasure.getIntValue() : 0;
75+
76+
final Measure killedMutantsMeasure = context.getMeasure(MutationMetrics.MUTATIONS_DETECTED.key());
77+
int killedMutants;
78+
double testStrength = 0;
79+
if (killedMutantsMeasure != null) {
80+
killedMutants = killedMutantsMeasure.getIntValue();
81+
int allMutantsQuantity = aliveMutants + killedMutants;
82+
if (allMutantsQuantity != 0) {
83+
testStrength = 100.0 * killedMutants / allMutantsQuantity;
84+
}
85+
}
86+
LOG.info("Computed Test Strength of {}% for {}", testStrength, context.getComponent());
87+
context.addMeasure(MutationMetrics.MUTATIONS_TEST_STRENGTH.key(), testStrength);
7288
} else {
7389
//modules with no mutants (0 total) are always 100% covered (0 of 0 is 100%, right?)
7490
context.addMeasure(MutationMetrics.MUTATIONS_COVERAGE.key(), 100.0);
91+
context.addMeasure(MutationMetrics.MUTATIONS_TEST_STRENGTH.key(), 100.0);
7592
}
7693
} else if(config.getBoolean(FORCE_MISSING_COVERAGE_TO_ZERO).orElse(Boolean.FALSE)){
7794
context.addMeasure(MutationMetrics.MUTATIONS_COVERAGE.key(), 0.0);
95+
context.addMeasure(MutationMetrics.MUTATIONS_TEST_STRENGTH.key(), 0.0);
7896
}
7997
}
8098
}

src/test/java/ch/devcon5/sonar/plugins/mutationanalysis/metrics/MutationMetricsTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class MutationMetricsTest {
3434
public void testMetricConstants() throws Exception {
3535

3636
assertNotNull(MutationMetrics.MUTATIONS_COVERAGE);
37+
assertNotNull(MutationMetrics.MUTATIONS_TEST_STRENGTH);
3738
assertNotNull(MutationMetrics.MUTATIONS_DATA);
3839
assertNotNull(MutationMetrics.MUTATIONS_DETECTED);
3940
assertNotNull(MutationMetrics.MUTATIONS_KILLED);

src/test/java/ch/devcon5/sonar/plugins/mutationanalysis/metrics/MutationScoreComputerTest.java

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,6 @@
2020

2121
package ch.devcon5.sonar.plugins.mutationanalysis.metrics;
2222

23-
import static ch.devcon5.sonar.plugins.mutationanalysis.metrics.MutationMetrics.MUTATIONS_COVERAGE_KEY;
24-
import static ch.devcon5.sonar.plugins.mutationanalysis.metrics.MutationMetrics.MUTATIONS_DETECTED_KEY;
25-
import static ch.devcon5.sonar.plugins.mutationanalysis.metrics.MutationMetrics.MUTATIONS_TOTAL_KEY;
26-
import static org.junit.Assert.assertEquals;
27-
import static org.junit.Assert.assertNull;
28-
import static org.junit.Assert.assertTrue;
29-
30-
import java.util.Arrays;
31-
3223
import ch.devcon5.sonar.plugins.mutationanalysis.MutationAnalysisPlugin;
3324
import ch.devcon5.sonar.plugins.mutationanalysis.testharness.MeasureComputerTestHarness;
3425
import org.junit.Before;
@@ -37,6 +28,17 @@
3728
import org.sonar.api.ce.measure.test.TestMeasureComputerContext;
3829
import org.sonar.api.ce.measure.test.TestMeasureComputerDefinitionContext;
3930

31+
import java.util.Arrays;
32+
import java.util.HashSet;
33+
34+
import static ch.devcon5.sonar.plugins.mutationanalysis.metrics.MutationMetrics.MUTATIONS_COVERAGE_KEY;
35+
import static ch.devcon5.sonar.plugins.mutationanalysis.metrics.MutationMetrics.MUTATIONS_DETECTED_KEY;
36+
import static ch.devcon5.sonar.plugins.mutationanalysis.metrics.MutationMetrics.MUTATIONS_SURVIVED_KEY;
37+
import static ch.devcon5.sonar.plugins.mutationanalysis.metrics.MutationMetrics.MUTATIONS_TEST_STRENGTH_KEY;
38+
import static ch.devcon5.sonar.plugins.mutationanalysis.metrics.MutationMetrics.MUTATIONS_TOTAL_KEY;
39+
import static org.junit.Assert.assertEquals;
40+
import static org.junit.Assert.assertNull;
41+
4042
public class MutationScoreComputerTest {
4143

4244
private MutationScoreComputer computer;
@@ -58,8 +60,8 @@ public void define() {
5860

5961
final MeasureComputer.MeasureComputerDefinition def = computer.define(context);
6062

61-
assertTrue(def.getInputMetrics().containsAll(Arrays.asList(MUTATIONS_DETECTED_KEY, MUTATIONS_TOTAL_KEY)));
62-
assertTrue(def.getOutputMetrics().containsAll(Arrays.asList(MUTATIONS_COVERAGE_KEY)));
63+
assertEquals(def.getInputMetrics(), new HashSet<>(Arrays.asList(MUTATIONS_DETECTED_KEY, MUTATIONS_TOTAL_KEY, MUTATIONS_SURVIVED_KEY)));
64+
assertEquals(def.getOutputMetrics(), new HashSet<>(Arrays.asList(MUTATIONS_COVERAGE_KEY, MUTATIONS_TEST_STRENGTH_KEY)));
6365
}
6466

6567
@Test
@@ -120,6 +122,21 @@ public void compute_3of5Mutations_to_60percentCoverage() {
120122

121123
}
122124

125+
@Test
126+
public void compute_1of5MutationsKilled_to_20percentTestStrength() {
127+
128+
final TestMeasureComputerContext measureContext = harness.createMeasureContextForSourceFile("compKey");
129+
130+
measureContext.addInputMeasure(MUTATIONS_TOTAL_KEY, 5);
131+
measureContext.addInputMeasure(MUTATIONS_SURVIVED_KEY, 4);
132+
measureContext.addInputMeasure(MUTATIONS_DETECTED_KEY, 1);
133+
134+
computer.compute(measureContext);
135+
136+
assertEquals(20.0, measureContext.getMeasure(MUTATIONS_TEST_STRENGTH_KEY).getDoubleValue(), 0.05);
137+
138+
}
139+
123140
@Test
124141
public void compute_NoCoveredElements_0percentCoverage() {
125142

@@ -130,6 +147,7 @@ public void compute_NoCoveredElements_0percentCoverage() {
130147
computer.compute(measureContext);
131148

132149
assertEquals(0.0, measureContext.getMeasure(MUTATIONS_COVERAGE_KEY).getDoubleValue(), 0.05);
150+
assertEquals(0.0, measureContext.getMeasure(MUTATIONS_TEST_STRENGTH_KEY).getDoubleValue(), 0.05);
133151

134152
}
135153

0 commit comments

Comments
 (0)