The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Running muttest in CI

Running mutation tests in CI gives you a persistent, objective record of test quality that evolves alongside your codebase. This guide covers GitHub Actions setup, badge reporting, and practical tips for keeping CI runs fast.

Why run mutation tests in CI

GitHub Actions: minimal workflow

Create .github/workflows/test-mutation.yaml:

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

name: Mutation Testing

jobs:
  mutation-test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: r-lib/actions/setup-r@v2
        with:
          use-public-rspm: true

      - uses: r-lib/actions/setup-r-dependencies@v2
        with:
          extra-packages: |
            jakubsob/muttest

      - name: Run mutation tests
        shell: Rscript {0}
        run: |
          plan <- muttest::muttest_plan(c(
            muttest::arithmetic_operators(),
            muttest::comparison_operators()
          ))
          muttest::muttest(plan)

Adjust source_files and mutators to match your package.

Mutation score badge

The muttest repository ships a badge workflow that writes a JSON endpoint to a badges branch and renders it as a shield. See the badge workflow in the muttest repository for the full implementation pattern.

The badge in your README looks like:

[![muttest](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/YOUR_ORG/YOUR_REPO/badges/badges/muttest.json)](https://github.com/YOUR_ORG/YOUR_REPO/actions/workflows/test-mutation.yaml)

Choosing which files to mutate in CI

Mutation testing multiplies your test runtime: running N mutants means running your test suite N times. Keep CI fast by being selective:

Mutate:

Skip:

A practical approach: define a narrow source_files list in your CI plan covering only the high-value files, and run the broader set locally or on a nightly schedule.

Failing the build on a low score

To enforce a minimum mutation score, parse the output or use R’s exit codes:

score <- muttest::muttest(plan)
if (score < 0.7) {
  message(sprintf("Mutation score %.1f%% is below threshold 70%%", score * 100))
  quit(status = 1)
}

Start with a threshold that reflects your current score, then tighten it over time as you improve your tests.

Performance tips

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.