Repository navigation
Add mutation testing via Infection - #899
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #899 +/- ##
=========================================
Coverage 99.71% 99.71%
Complexity 1970 1970
=========================================
Files 147 147
Lines 4488 4488
=========================================
Hits 4475 4475
Misses 13 13 ☔ View full report in Codecov by Harness. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Firehed
marked this pull request as ready for review
November 3, 2026 22:08
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Review keeps asking one question by hand: does any test notice if a changed line is wrong?
Each reviewer tries the changes they think of, so each round finds a few more, and a review never comes back clean.
Coverage does not answer it either: a covered line can still be wrong without any test failing.
Change
Adds Infection, a mutation-testing tool, as a check on pull requests.
It makes small changes (flipping a comparison, removing a call, swapping a value) to each line of
src/that a branch changed, reruns the unit tests that cover the line, and reports every change that nothing notices.The list is complete for its kinds of change and the same on every run.
infection/infectionas a dev dependency, pinned to an exact version so local and CI runs match (composer.lockis gitignored). Its Composer plugin, which only installs Infection extensions, is not allowed.infection.json5: mutatessrc/, runs the unit suite only, counts a change PHPStan rejects as caught (PHPStan already gates every change), and fails unless every change is caught. A run with nothing to mutate passes.composer mutation: mutates the lines changed sinceorigin/main. It fails locally exactly as it does in CI.Mutation Testingjob on pull requests runscomposer mutationwith the same setup as the unit job, assertions enabled. Without assertions, changes the tests catch through anassert()would survive only in CI. Surviving changes appear as annotations on the diff, and the job fails while any survive; an annotation on a passing check was easy to miss.- CONTRIBUTING.md: how to run it, and what to do with a surviving change. A change no input could detect is resolved by rewriting the code so the change cannot be made, or else by an approvedClass::methodignore entry. Tests name the behavior they check, not the change they catch.Known limits
origin/main; CI tests the pull request merged withmain.🤖 Generated with Claude Code