Stryker.NET version: 4.16.0
Coverage analysis: perTest (CoverageBasedTest)
Summary
A mutant was reported Survived although two tests that kill it were present in the run. The mutant's coveredBy list did not include those tests — they appear to have been missed by the per-test coverage mapping, so the mutant never ran against them.
Reproduction outline
- A
Block removal mutant inside a private helper (SkipValue, a JSON-ish scanner) survived a full run (388–390 tests, all green).
mutation-report.json for that mutant listed only 6 covering tests — all older tests; two recently added tests that explicitly exercise the mutated branch ("a":"a\"}" style inputs where string-aware skipping is the whole point) were absent from coveredBy.
- Manually applying the identical mutation (removing the block body) and running only those two tests: both fail → the mutant is killable, not equivalent.
So the effective score was understated: Survived: 1 in the report, ground truth Survived: 0.
Impact
- False survivors mislead equivalent-mutant triage: reviewers spend effort constructing equivalence proofs for mutants that are actually killed by tests the mapper missed.
- Silent: nothing in the report suggests the coverage map is incomplete.
Environment
- .NET 8.0, xUnit 2.9.2 (Theory-heavy suite; the missed tests were
[Fact]s added in the same session, file rebuilt before the run — Number of tests found included them).
- The killed-by-omission tests cover exactly the mutated lines (verified via coverlet line data).
Suggestion
When a mutant is marked Survived, consider a diagnostic mode that re-runs it against tests covering the mutant's line range per the raw coverage data (or at minimum flags survivors whose coveredBy set looks suspiciously small relative to line coverage).
Stryker.NET version: 4.16.0
Coverage analysis: perTest (CoverageBasedTest)
Summary
A mutant was reported Survived although two tests that kill it were present in the run. The mutant's
coveredBylist did not include those tests — they appear to have been missed by the per-test coverage mapping, so the mutant never ran against them.Reproduction outline
Block removalmutant inside a private helper (SkipValue, a JSON-ish scanner) survived a full run (388–390 tests, all green).mutation-report.jsonfor that mutant listed only 6 covering tests — all older tests; two recently added tests that explicitly exercise the mutated branch ("a":"a\"}"style inputs where string-aware skipping is the whole point) were absent fromcoveredBy.So the effective score was understated:
Survived: 1in the report, ground truthSurvived: 0.Impact
Environment
[Fact]s added in the same session, file rebuilt before the run —Number of tests foundincluded them).Suggestion
When a mutant is marked Survived, consider a diagnostic mode that re-runs it against tests covering the mutant's line range per the raw coverage data (or at minimum flags survivors whose coveredBy set looks suspiciously small relative to line coverage).