-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Resolve Pitest Suppressions #12341
Description
This issue will be the main tracker issue for resolving Pitest suppressions.
Summary
Surviving pit mutations are a form of technical debt, and we would like to kill all surviving mutations. It is important to first understand what pitest is and how it works. Please visit https://pitest.org/ to learn about this tool. Simply put, pitest changes our code using mutation operators (this changed code is now called a mutation), then runs our tests against this changed code. If some test fails due to the changed code, then the mutation is considered "killed". If not, then the mutation has survived, and we need to (ideally) find a test input to kill the mutation.
The point of this issue is to find a test case that kills a surviving mutation.
How does Pitest work?
Let's take a look at a suppressed surviving mutation:
checkstyle/.ci/pitest-suppressions/pitest-blocks-suppressions.xml
Lines 156 to 163 in 5768a5e
| <mutation unstable="false"> | |
| <sourceFile>RightCurlyCheck.java</sourceFile> | |
| <mutatedClass>com.puppycrawl.tools.checkstyle.checks.blocks.RightCurlyCheck$Details</mutatedClass> | |
| <mutatedMethod>getDetailsForOthers</mutatedMethod> | |
| <mutator>org.pitest.mutationtest.engine.gregor.mutators.experimental.NakedReceiverMutator</mutator> | |
| <description>replaced call to com/puppycrawl/tools/checkstyle/api/DetailAST::getFirstChild with receiver</description> | |
| <lineContent>lcurly = child.getFirstChild();</lineContent> | |
| </mutation> |
The above suppression is for a mutation operator that took this original line of code:
checkstyle/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyCheck.java
Line 651 in 5768a5e
| lcurly = child.getFirstChild(); |
And mutated it into this code (now called a mutant or mutation):
lcurly = lcurly;The mutation is considered to have "survived", which means that no test failed after the code was changed. We want to find a test case that will fail if this mutation is in the code.
How do I select a mutation to work on?
Visit https://github.com/checkstyle/checkstyle/tree/master/.ci/pitest-suppressions, take a look through any of the suppression files there, and pick one mutation to work on.
How do I resolve a pitest suppression?
- Pick a single mutation suppression from a file in https://github.com/checkstyle/checkstyle/tree/master/.ci/pitest-suppressions
- Create a new issue, with a permalink to the suppression.
- Send PR with single hardcoded mutation only (ex: change
lcurly = child.getFirstChild();tolcurly =lcurly;) - If any tests or continuous integration testing (ex:
no-exception testing) are failing, you might have found a test case to kill the mutation. - If a test case is not found in step (4), then generate a check regression report. See https://github.com/checkstyle/contribution/tree/master/checkstyle-tester#report-generation for details. Any differences or exceptions in the report are probably a new test case.
- If a test case still cannot be found, provide an analysis of why we cannot find a test case to kill this mutation, and share it in the issue you've created for discussion with maintainers.
Once a possible test case is found, create a new test and new test input for it, generate the pitest report locally to verify. See https://github.com/checkstyle/checkstyle/wiki/How-to-Generate-and-Analyze-Pitest-Reports#how-to-generate-pit-report for details on this.
The procedure for resolution of pitest suppressions can be found in the below diagram:
Required reading:
https://github.com/checkstyle/checkstyle/wiki/How-to-Generate-and-Analyze-Pitest-Reports
Example pull requests:
https://github.com/checkstyle/checkstyle/pulls?q=is%3Apr+is%3Amerged+%22kill+surviving+mutation%22