Skip to content
Back to skills

Pitest Mutation

ASecurity

Configures PIT (PITest) for mutation testing of JVM projects (Java, Kotlin via the Kotlin plugin) - wires the `pitest-maven` or `pitest-gradle-plugin` with `mutationThreshold`, `coverageThreshold`, target classes/tests filtering, runs `mvn pitest:mutationCoverage`, parses the HTML + XML reports. Use when the JVM suite needs mutation-quality verification - the canonical Java mutation testing tool, fast (PIT analyzes \"in minutes rather than days\").

  • 10 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 12, 2026
testingjavakotlinbashspringtestinggit

Security analysis

A100/100

Pro scans all 13 files and shows the line behind each finding

Scanned October 12, 2026

npx -y skills add testland/qa --skill pitest-mutation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Pitest Mutation?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Pitest Mutation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/testland-pitest-mutation/badge)](https://www.skillsdirectory.com/skills/testland-pitest-mutation)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: pitest-mutation
description: "Configures PIT (PITest) for mutation testing of JVM projects (Java, Kotlin via the Kotlin plugin) - wires the `pitest-maven` or `pitest-gradle-plugin` with `mutationThreshold`, `coverageThreshold`, target classes/tests filtering, runs `mvn pitest:mutationCoverage`, parses the HTML + XML reports. Use when the JVM suite needs mutation-quality verification - the canonical Java mutation testing tool, fast (PIT analyzes \"in minutes rather than days\")."
---

# pitest-mutation

## Overview

Per [pit-home][pit]:

[pit]: https://pitest.org/

> "PIT is a mutation testing system for Java and JVM applications.
> It automatically introduces faults into code, then runs tests to
> see if they catch these modifications."
>
> "Faults (or mutations) are automatically seeded into your code,
> then your tests are run. If your tests fail then the mutation is
> killed, if your tests pass then the mutation lived."
> ([pit-home][pit])

Per [pit-home][pit], PIT differentiates on **speed**: "analyzes in
minutes rather than days" vs older mutation tools.

## When to use

- A JVM project (Java, Kotlin via plugin) needs mutation-quality
  verification.
- A team wants to identify "partial testing that traditional metrics
  miss" ([pit-home][pit]).
- Maven / Gradle integration is required (PIT is first-class for
  both).

## How to use

1. Add the `pitest-maven` (or `info.solidsoft.pitest` Gradle) plugin, including `pitest-junit5-plugin` for JUnit 5 suites.
2. Point `targetClasses` at production packages and `targetTests` at the matching test packages - never mutate test code.
3. Set `mutationThreshold` and `coverageThreshold` to the current baseline and request HTML + XML `outputFormats`.
4. Run `mvn pitest:mutationCoverage` (or `./gradlew pitest`) and open `target/pit-reports/<timestamp>/index.html`.
5. For each surviving mutant, add or strengthen a test until it is killed.
6. Use `-DwithHistory` for PR runs so only changed code is re-mutated.
7. In CI, run full weekly and incremental per-PR, uploading `target/pit-reports/` as an artifact.

## Step 1 - Install (Maven)

```xml
<plugin>
  <groupId>org.pitest</groupId>
  <artifactId>pitest-maven</artifactId>
  <version>1.17.0</version>
  <configuration>
    <targetClasses>
      <param>com.example.checkout.*</param>
    </targetClasses>
    <targetTests>
      <param>com.example.checkout.*Test</param>
    </targetTests>
    <mutationThreshold>75</mutationThreshold>
    <coverageThreshold>80</coverageThreshold>
    <outputFormats>
      <format>HTML</format>
      <format>XML</format>
    </outputFormats>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.pitest</groupId>
      <artifactId>pitest-junit5-plugin</artifactId>
      <version>1.2.1</version>
    </dependency>
  </dependencies>
</plugin>
```

For JUnit 5, the `pitest-junit5-plugin` is required; for JUnit 4
the default plugin works.

## Step 2 - Run

```bash
mvn pitest:mutationCoverage
```

Reports land at `target/pit-reports/<timestamp>/`. The
`index.html` shows per-class mutation coverage.

## Step 3 - Configure (Gradle)

```gradle
plugins {
    id 'java'
    id 'info.solidsoft.pitest' version '1.15.0'
}

pitest {
    targetClasses = ['com.example.checkout.*']
    targetTests = ['com.example.checkout.*Test']
    mutationThreshold = 75
    coverageThreshold = 80
    outputFormats = ['HTML', 'XML']
    junit5PluginVersion = '1.2.1'
}

// Run via:
// ./gradlew pitest
```

## Step 4 - Mutators

PIT's default mutator set covers conditional, arithmetic, return
value, void method calls, and constructor calls. Activate
additional mutator sets via `<mutators>`:

```xml
<mutators>
  <mutator>STRONGER</mutator>     <!-- All default + extra -->
  <mutator>DEFAULTS</mutator>     <!-- Default set -->
  <mutator>ALL</mutator>          <!-- Everything -->
</mutators>
```

Per [pit-home][pit], reports "combine line coverage with mutation
coverage data."

## Step 5 - `pitmp-maven-plugin` for incremental runs

For PRs, only mutate changed code:

```bash
mvn pitest:mutationCoverage -DwithHistory
```

`withHistory` reads / writes a history file in `target/`; subsequent
runs only mutate code different from the cached history. For PR
runs, combine with git diff to scope further:

```bash
mvn pitest:mutationCoverage \
  -Dfeatures='+gitci(level[1])' \
  -Dpitmp.git.diff.target=origin/main
```

(The `pitmp-maven-plugin` extension adds git-diff-based scoping;
not in core PIT.)

## Step 6 - CI integration

```yaml
- uses: actions/setup-java@v4
  with: { distribution: temurin, java-version: '21' }

- name: Mutation testing (full)
  if: github.event_name == 'schedule'  # weekly cron
  run: mvn pitest:mutationCoverage

- name: Mutation testing (incremental, PR)
  if: github.event_name == 'pull_request'
  run: mvn pitest:mutationCoverage -DwithHistory

- uses: actions/upload-artifact@v4
  if: always()
  with:
    name: pit-reports
    path: target/pit-reports/
```

The XML output (`mutations.xml`) is machine-parseable for
dashboards.

## Step 7 - Kotlin support

PIT works with Kotlin via standard Maven/Gradle Kotlin plugins;
mutators apply to compiled bytecode. Per [pit-home][pit], "ArcMutate,
from the same team, extends PIT with Kotlin support, Spring
integration, and Git analysis" - for richer Kotlin / Spring
support, evaluate ArcMutate (commercial).

## Worked example

`CheckoutService` in `com.example.checkout` has a free-shipping rule and green JUnit 5 tests.

1. Wire the plugin (Step 1) with `targetClasses` = `com.example.checkout.*`, `targetTests` = `com.example.checkout.*Test`, `mutationThreshold` = 75.
2. `mvn pitest:mutationCoverage` writes `target/pit-reports/<timestamp>/index.html` and fails the build below the 75 threshold.
3. `index.html` flags a survivor: the free-shipping boundary `total >= 50` mutated to `total > 50`, uncaught because no test uses `total == 50`.
4. Add a JUnit 5 test at the `total == 50` boundary; `mvn pitest:mutationCoverage` now kills the mutant and clears the threshold.
5. Switch the PR job to `-DwithHistory` so later runs only re-mutate changed classes.

## Pitfalls and limitations

Anti-patterns (mutating everything per PR, `mutationThreshold: 100`, mixed Maven/Gradle config, missing JUnit 5 plugin, targeting test classes, the `ALL` mutator set) and PIT's limitations (bytecode-level equivalent mutants, build-tool coupling, commercial Kotlin / Spring extras, per-class scope) are catalogued in [references/pitest-pitfalls.md](references/pitest-pitfalls.md).

## References

- [pit][pit] - PIT overview: mutation testing definition, JVM-only,
  speed claim ("minutes rather than days"), Maven/Gradle/Ant
  integration, ArcMutate Pro extension.
- `stryker-mutation`,
  `stryker-net-mutation`,
  `mutmut-mutation`,
  `mull-mutation` - per-language
  siblings.

Files in this skill

  • .tessl-plugin/plugin.json584 B
  • SKILL.md6.7 KB
  • evals/hundred-percent-mandate-three-weeks-before-the-audit/criteria.json6.2 KB
  • evals/hundred-percent-mandate-three-weeks-before-the-audit/task.md14.7 KB
  • evals/kotlin-module-the-director-wants-at-java-parity/criteria.json5.9 KB
  • evals/kotlin-module-the-director-wants-at-java-parity/task.md11.5 KB
  • evals/mutation-gate-reports-zero-after-the-junit5-migration/criteria.json6.1 KB
  • evals/mutation-gate-reports-zero-after-the-junit5-migration/task.md11.8 KB
  • evals/three-hour-pr-job-the-team-has-stopped-waiting-for/criteria.json5.6 KB
  • evals/three-hour-pr-job-the-team-has-stopped-waiting-for/task.md8.9 KB
  • evals/two-build-files-two-scores-before-the-release-tag/criteria.json6.3 KB
  • evals/two-build-files-two-scores-before-the-release-tag/task.md11.7 KB
  • references/pitest-pitfalls.md1.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.