Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Covered by tests" list for every survived mutation in HTML report #1340

Merged
merged 3 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -51,10 +52,12 @@ private MutationResult xmlToResult(MutationXml xml) {
Location location = new Location(ClassName.fromString(xml.mutatedClass),
xml.mutatedMethod, xml.methodDescription);
MutationIdentifier id = new MutationIdentifier(location, xml.indexes, xml.mutator);
String[] killingTests = xml.killingTest == null ? new String[0] : new String[] { xml.killingTest };
String[] succeedingTests = xml.succeedingTests == null ? new String[0] : xml.succeedingTests.split(",");
return new MutationResult(new MutationDetails(id,
xml.sourceFile, xml.description,
xml.lineNumber, xml.blocks),
new MutationStatusTestPair(xml.numberOfTestsRun, DetectionStatus.valueOf(xml.status), xml.killingTest));
new MutationStatusTestPair(xml.numberOfTestsRun, DetectionStatus.valueOf(xml.status), Arrays.asList(killingTests), Arrays.asList(succeedingTests), Arrays.asList(succeedingTests)));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import java.util.Objects;
import java.util.Optional;
import org.pitest.mutationtest.engine.MutationDetails;

public final class MutationResult {

private final MutationDetails details;
Expand All @@ -30,6 +29,9 @@ public MutationResult(final MutationDetails md,
this.status = status;
}

public String getId() {
return this.details.getId().toString().replace(" ","-");
}
public MutationDetails getDetails() {
return this.details;
}
Expand All @@ -46,6 +48,10 @@ public List<String> getSucceedingTests() {
return this.status.getSucceedingTests();
}

public List<String> getCoveringTests() {
return this.status.getCoveringTests();
}

public DetectionStatus getStatus() {
return this.status.getStatus();
}
Expand All @@ -66,6 +72,10 @@ public String getKillingTestDescription() {
return getKillingTest().orElse("none");
}

public Boolean getSurvived() {
return this.status.getStatus() == DetectionStatus.SURVIVED;
}

@Override
public int hashCode() {
return Objects.hash(details, status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
*/
package org.pitest.mutationtest;

import static org.pitest.functional.prelude.Prelude.putToMap;

import java.util.Collection;
import java.util.Collections;
Expand All @@ -27,6 +26,7 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.pitest.coverage.TestInfo;
import org.pitest.functional.FCollection;
import org.pitest.mutationtest.engine.MutationDetails;

Expand All @@ -46,7 +46,11 @@ public void setStatusForMutation(final MutationDetails mutation,

public void setStatusForMutations(
final Collection<MutationDetails> mutations, final DetectionStatus status) {
mutations.forEach(putToMap(this.mutationMap, MutationStatusTestPair.notAnalysed(0, status)));
mutations.forEach(mutationDetails -> {
List<String> coveringTests = mutationDetails.getTestsInOrder().stream().map(TestInfo::getName).collect(Collectors.toList());
MutationStatusTestPair pair = MutationStatusTestPair.notAnalysed(0, status, coveringTests);
mutationMap.put(mutationDetails, pair);
});
}

public List<MutationResult> createMutationResults() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private void handleReport(final SafeDataInputStream is) {
private void handleDescribe(final SafeDataInputStream is) {
final MutationIdentifier mutation = is.read(MutationIdentifier.class);
this.idMap.put(mutation, MutationStatusTestPair.notAnalysed(1,
DetectionStatus.STARTED));
DetectionStatus.STARTED,null));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ private MutationResult makeResult(final MutationDetails each,
final List<String> succeedingTests) {
updatePreanalysedTotal(status);
return new MutationResult(each, new MutationStatusTestPair(0, status,
killingTests, succeedingTests));
killingTests, succeedingTests, each.getTestsInOrder().stream()
.map(TestInfo::getName).collect(Collectors.toList())));
}

private void updatePreanalysedTotal(final DetectionStatus status) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,23 @@
*/
package org.pitest.mutationtest.report.xml;

import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import org.apache.commons.text.StringEscapeUtils;
import org.pitest.mutationtest.ClassMutationResults;
import org.pitest.mutationtest.MutationResult;
import org.pitest.mutationtest.MutationResultListener;
import org.pitest.mutationtest.engine.MutationDetails;
import org.pitest.util.ResultOutputStrategy;
import org.pitest.util.Unchecked;

import static org.pitest.mutationtest.report.xml.Tag.block;
import static org.pitest.mutationtest.report.xml.Tag.blocks;
import static org.pitest.mutationtest.report.xml.Tag.coveringTests;
import static org.pitest.mutationtest.report.xml.Tag.description;
import static org.pitest.mutationtest.report.xml.Tag.index;
import static org.pitest.mutationtest.report.xml.Tag.indexes;
Expand All @@ -30,22 +45,8 @@
import static org.pitest.mutationtest.report.xml.Tag.sourceFile;
import static org.pitest.mutationtest.report.xml.Tag.succeedingTests;

import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import org.apache.commons.text.StringEscapeUtils;
import org.pitest.mutationtest.ClassMutationResults;
import org.pitest.mutationtest.MutationResult;
import org.pitest.mutationtest.MutationResultListener;
import org.pitest.mutationtest.engine.MutationDetails;
import org.pitest.util.ResultOutputStrategy;
import org.pitest.util.Unchecked;

enum Tag {
mutation, sourceFile, mutatedClass, mutatedMethod, methodDescription, lineNumber, mutator, indexes, index, killingTest, killingTests, succeedingTests, description, blocks, block
mutation, sourceFile, mutatedClass, mutatedMethod, methodDescription, lineNumber, mutator, indexes, index, killingTest, killingTests, succeedingTests, coveringTests, description, blocks, block
}

public class XMLReportListener implements MutationResultListener {
Expand Down Expand Up @@ -101,6 +102,8 @@ private String makeMutationNode(final MutationResult mutation) {
createTestDesc(mutation.getKillingTests()), killingTests)
+ makeNodeWhenConditionSatisfied(fullMutationMatrix,
createTestDesc(mutation.getSucceedingTests()), succeedingTests)
+ makeNodeWhenConditionSatisfied(fullMutationMatrix,
createTestDesc(mutation.getCoveringTests()), coveringTests)
+ makeNode(clean(details.getDescription()), description);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private MutationResult makeResult(String clazz, String method) {
final MutationDetails md = aMutationDetail().withId(
aMutationId().withLocation(location)).build();
return new MutationResult(md,
MutationStatusTestPair.notAnalysed(0, DetectionStatus.KILLED));
MutationStatusTestPair.notAnalysed(0, DetectionStatus.KILLED,Collections.emptyList()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import nl.jqno.equalsverifier.EqualsVerifier;

import java.util.Collections;

public class MutationResultTest {

private MutationResult testee;
Expand All @@ -34,14 +36,14 @@ public void shouldReturnNameOfKillingTestWhenKnown() {
@Test
public void shouldNoneWhenNoKillingTest() {
this.testee = new MutationResult(null, MutationStatusTestPair.notAnalysed(1,
DetectionStatus.TIMED_OUT));
DetectionStatus.TIMED_OUT, Collections.emptyList()));
assertEquals("none", this.testee.getKillingTestDescription());
}

@Test
public void shouldReturnStatusDescription() {
this.testee = new MutationResult(null, MutationStatusTestPair.notAnalysed(1,
DetectionStatus.TIMED_OUT));
DetectionStatus.TIMED_OUT,Collections.emptyList()));
assertEquals("TIMED_OUT", this.testee.getStatusDescription());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@

import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;

import com.google.common.collect.Lists;
import org.junit.Before;
import org.junit.Test;
import org.pitest.classinfo.ClassName;
import org.pitest.coverage.TestInfo;
import org.pitest.mutationtest.LocationMother.MutationIdentifierBuilder;
import org.pitest.mutationtest.engine.MutationDetails;

Expand All @@ -23,12 +27,18 @@ public class MutationStatusMapTest {

private MutationDetails detailsTwo;

private MutationDetails aSurvivedMutationDetails;

@Before
public void setUp() {
this.testee = new MutationStatusMap();
final MutationIdentifierBuilder id = aMutationId().withIndex(1);
this.details = aMutationDetail().withId(id.withIndex(1)).build();
this.detailsTwo = aMutationDetail().withId(id.withIndex(2)).build();

TestInfo fooTest = new TestInfo("foo", "foo", 0, Optional.ofNullable(ClassName.fromString("com.foo")), 0);
TestInfo barTest = new TestInfo("bar", "bar", 0, Optional.ofNullable(ClassName.fromString("com.foo")), 0);
this.aSurvivedMutationDetails = aMutationDetail().withId(id.withIndex(3)).withTestsInOrder(Lists.asList(fooTest, new TestInfo[]{barTest})).build();
}

@Test
Expand Down Expand Up @@ -92,6 +102,19 @@ public void shouldCreateResultsForAllMutations() {
resultTwo);
}

@Test
public void shouldCreateResultsForSurvivedMutations(){
final MutationStatusTestPair statusPairOne = new MutationStatusTestPair(42,
DetectionStatus.SURVIVED, Collections.singletonList("foo"),Arrays.asList("foo1","bar"), Arrays.asList("foo","foo1","bar"));
this.testee.setStatusForMutation(this.aSurvivedMutationDetails, statusPairOne);

assertEquals(DetectionStatus.SURVIVED, this.testee.createMutationResults().get(0).getStatus());
assertThat(this.testee.createMutationResults().get(0).getKillingTests()).contains("foo");
assertThat(this.testee.createMutationResults().get(0).getSucceedingTests()).contains("foo1","bar");
assertThat(this.testee.createMutationResults().get(0).getCoveringTests()).contains("foo","foo1","bar");

}

@Test
public void shouldSetStatusToUncoveredWhenMutationHasNoTests() {
this.testee.setStatusForMutations(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.junit.Before;
Expand Down Expand Up @@ -63,7 +64,7 @@ public void shouldReportWhenMutationsNotCoveredByAnyTest() throws Exception {
this.tests.add(ClassName.fromString("foo"));
final MutationMetaData actual = this.testee.call();
final MutationResult expected = new MutationResult(this.mutations.get(0),
MutationStatusTestPair.notAnalysed(0, DetectionStatus.NO_COVERAGE));
MutationStatusTestPair.notAnalysed(0, DetectionStatus.NO_COVERAGE, Collections.emptyList()));
assertThat(actual.getMutations()).contains(expected);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.pitest.mutationtest.report.MutationTestResultMother;

import java.util.Collection;
import java.util.Collections;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -37,7 +38,7 @@ public void recordsMutationResults() {
private MutationResult makeResult() {
return new MutationResult(
MutationTestResultMother.createDetails(), MutationStatusTestPair.notAnalysed(0,
DetectionStatus.KILLED));
DetectionStatus.KILLED, Collections.emptyList()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ public void assessMultipleMutationsAtATime() {
0,
KILLED,
singletonList(killingTest),
emptyList(),
emptyList())));

when(this.history.getPreviousResult(md2.getId()))
Expand All @@ -314,11 +315,12 @@ public void assessMultipleMutationsAtATime() {
0,
KILLED,
singletonList(killingTest),
emptyList(),
emptyList())));

when(this.history.getPreviousResult(md3.getId()))
.thenReturn(Optional.of(
new MutationStatusTestPair(0, SURVIVED, emptyList(), emptyList())));
new MutationStatusTestPair(0, SURVIVED, emptyList(), emptyList(),emptyList())));

when(this.history.getPreviousResult(md4.getId()))
.thenReturn(Optional.empty());
Expand Down Expand Up @@ -414,7 +416,7 @@ private void setHistoryForAllMutationsTo(final DetectionStatus status,
final String... test) {
when(this.history.getPreviousResult(any(MutationIdentifier.class)))
.thenReturn(Optional.of(
new MutationStatusTestPair(0, status, asList(test), emptyList())));
new MutationStatusTestPair(0, status, asList(test), emptyList(), emptyList())));
}

private static class LogCatcher extends Handler {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public interface MutationTestResultBuilder extends SequenceBuilder<MutationResul
public static MutationTestResultBuilder aMutationTestResult() {
return QB.builder(MutationTestResultBuilder.class, seed())
.withMutationDetails(aMutationDetail())
.withStatusTestPair(MutationStatusTestPair.notAnalysed(0, DetectionStatus.SURVIVED));
.withStatusTestPair(MutationStatusTestPair.notAnalysed(0, DetectionStatus.SURVIVED, Collections.emptyList()));
}

private static Generator<MutationTestResultBuilder, MutationResult> seed() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import java.io.Writer;
import java.util.Collections;

import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -71,7 +72,7 @@ public void shouldQuoteKillingTestWhenNeeded() throws IOException {
public void shouldOutputNoneWhenNoKillingTestFound() throws IOException {
final MutationResult mr = new MutationResult(
MutationTestResultMother.createDetails(), MutationStatusTestPair.notAnalysed(1,
DetectionStatus.SURVIVED));
DetectionStatus.SURVIVED, Collections.emptyList()));
this.testee.handleMutationResult(MutationTestResultMother
.createClassResults(mr));
final String expected = "file,clazz,mutator,method,42,SURVIVED,none"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;

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

Expand Down Expand Up @@ -64,12 +65,12 @@ public void shouldOutputFullMutationMatrixWhenEnabled() {
this.testee = new XMLReportListener(this.out, true, false);
final MutationResult mr = new MutationResult(
MutationTestResultMother.createDetails(),
new MutationStatusTestPair(3, DetectionStatus.KILLED, Arrays.asList("foo", "foo2"), Arrays.asList("bar")));
new MutationStatusTestPair(3, DetectionStatus.KILLED, Arrays.asList("foo", "foo2"), Arrays.asList("bar"), Arrays.asList("foo","foo2","bar")));
this.testee
.handleMutationResult(MutationTestResultMother.createClassResults(mr));
final String expected = "<mutation detected='true' status='KILLED' numberOfTestsRun='3'><sourceFile>file</sourceFile>" +
"<mutatedClass>clazz</mutatedClass><mutatedMethod>method</mutatedMethod><methodDescription>()I</methodDescription><lineNumber>42</lineNumber><mutator>mutator</mutator>" +
"<indexes><index>1</index></indexes><blocks><block>0</block></blocks><killingTests>foo|foo2</killingTests><succeedingTests>bar</succeedingTests><description>desc</description></mutation>\n";
"<indexes><index>1</index></indexes><blocks><block>0</block></blocks><killingTests>foo|foo2</killingTests><succeedingTests>bar</succeedingTests><coveringTests>foo|foo2|bar</coveringTests><description>desc</description></mutation>\n";
assertThat(expected).isEqualTo(this.out.toString());
}

Expand Down Expand Up @@ -110,7 +111,7 @@ public void shouldOutputNoneWhenNoKillingTestFound() throws IOException {
private MutationResult createSurvivingMutant() {
return new MutationResult(
MutationTestResultMother.createDetails(),
MutationStatusTestPair.notAnalysed(1, DetectionStatus.SURVIVED));
MutationStatusTestPair.notAnalysed(1, DetectionStatus.SURVIVED,Arrays.asList("foo","bar")));
}

}
Loading
Loading