Skip to main content

pytest-gremlins

Fast-first mutation testing for pytest. Speed that makes mutation testing practical for everyday TDD.

PyPI version Python versions CI codecov Documentation License: MIT

Let the gremlins loose. See which ones survive.


Key Features

  • Speed-First Architecture - Mutation switching eliminates file I/O and module reloads. Run gremlins in seconds, not hours.
  • Native pytest Integration - Zero configuration to start. Just add --gremlins to your pytest command.
  • Coverage-Guided Selection - Only runs tests that actually cover the mutated code. 10-100x fewer test executions in well-modularized codebases.
  • Incremental Caching - Results cached by content hash. Unchanged code skips re-testing entirely.
  • Parallel Execution - Distribute gremlins across CPU cores for linear speedup.

Quick Start

# Install
pip install pytest-gremlins

# Run mutation testing
pytest --gremlins

That's it. pytest-gremlins will instrument your code, release the gremlins, and report which ones your tests zapped (good!) and which survived (test gaps!).


Why pytest-gremlins?

Code coverage lies. It tells you what code your tests execute, but not whether your tests would catch bugs.

Mutation testing answers a harder question: If I introduce a bug, will my tests fail?

The Problem with Existing Tools

Tool Limitation
mutmut Unix/WSL only (requires fork()); not a pytest plugin
Cosmic Ray Complex setup; distributed mode requires Celery
MutPy Unmaintained (last update 2019), Python 3.4-3.7 only
mutatest Unmaintained (last update 2022)

See the full comparison guide for detailed, fair comparisons.

Our Solution: Speed Through Architecture

pytest-gremlins is fast because of how it works, not just parallelization:

  1. Mutation Switching - Instrument once, toggle mutations via environment variable
  2. Coverage Guidance - Only run tests that cover the mutated code
  3. Incremental Analysis - Skip unchanged code on repeat runs
  4. Parallel Execution - Safe parallelization with no shared state

Performance

Benchmarked against mutmut on a synthetic project:

Mode Time vs mutmut Speedup
--gremlins (sequential) 17.79s 14.90s 0.84x (see note)
--gremlins --gremlin-parallel 3.99s 14.90s 3.73x faster
--gremlins --gremlin-parallel --gremlin-cache 1.08s 14.90s 13.82x faster

Key findings:

  • Sequential mode is slower due to subprocess isolation overhead; detailed profiling shows 1.7x slower on small targets
  • Parallel mode delivers 3.73x speedup over mutmut
  • With caching, subsequent runs are 13.82x faster
  • pytest-gremlins found 117 mutations vs mutmut's 86, with 98% kill rate vs 86%

Example Output

================== pytest-gremlins mutation report ==================

Zapped: 142 gremlins (85%)
Survived: 18 gremlins (11%)
Timeout: 5 gremlins (3%)
Error: 2 gremlins (1%)

Top surviving gremlins:
  src/auth.py:42                   >= to >               (comparison)
  src/utils.py:17                  + to -                (arithmetic)
  src/api.py:88                    True to False         (boolean)

Run with --gremlin-report=html for detailed report.
=====================================================================

Timeout, Error, and Pardoned categories are only shown when their count is greater than zero.


Installation

# With pip
pip install pytest-gremlins

# With uv
uv add pytest-gremlins

# With poetry
poetry add pytest-gremlins

Requires Python 3.11+


Configuration

Zero configuration required for most projects. The plugin auto-discovers source paths from your pyproject.toml setuptools config (e.g., [tool.setuptools.packages.find]). If auto-discovery doesn't find your code, configure paths explicitly:

[tool.pytest-gremlins]
# Operators to use (default: all 5)
operators = ["comparison", "arithmetic", "boolean", "boundary", "return"]

# Paths to mutate (optional -- auto-discovered from setuptools metadata)
paths = ["src"]

# Patterns to exclude
exclude = ["**/migrations/*", "**/test_*"]

# Report formats: "console", "html", "json" (default: console)
report = ["console", "html"]

# Enable incremental caching (default: false)
cache = true

# Fail if pardoned gremlins exceed 5% of total
max-pardons-pct = 5.0

The Gremlins Theme

We use Gremlins movie references as our domain language:

Traditional Term Gremlin Term Meaning
Original code Mogwai Your clean, untouched source code
Start mutation testing Feed after midnight Begin the mutation process
Mutant Gremlin A mutation injected into your code
Kill mutant Zap Your test caught the mutation
Surviving mutant Survivor Mutation your tests missed

Documentation

Full documentation: pytest-gremlins.readthedocs.io


Related Projects


Contributing

Contributions welcome! See our Contributing Guide.

This project uses strict TDD discipline with BDD/Gherkin scenarios. All contributions must include tests written before implementation.

Note on code coverage: We target 69% coverage due to inherent limitations in measuring pytest plugins (import timing, subprocess execution). See CONTRIBUTING.md for details.


License

MIT License. See LICENSE.


Changelog

See CHANGELOG.md for release history.

Release files for pytest-gremlins 1.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-gremlins 1.9.0
File Size Uploaded
pytest_gremlins-1.9.0.tar.gz 4.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-gremlins 1.9.0
File Interpreter ABI Platform
pytest_gremlins-1.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 4.1 MB

Release files / pytest_gremlins-1.9.0.tar.gz

Download URL pytest_gremlins-1.9.0.tar.gz
Size 4.0 MB
Tags Source
SHA-256 checksum
How to use checksums
12966b4d24146b46d58aa1dc8a6d0881918863ca4454a44d109b295f22d27c24
BLAKE2b-256 checksum
How to use checksums
3bb674470cd5b97eb0cf5f3d7e2ef7feb2d6136b5cbe2df6e070299c5faf5e7c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 1, 2026.

Transparency log

Release files / pytest_gremlins-1.9.0-py3-none-any.whl

Download URL pytest_gremlins-1.9.0-py3-none-any.whl
Size 118.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
26997e1e6ac0cbdef70c68ddadbbd2bf93c7d41e143d9f2d84ec318b7d552b67
BLAKE2b-256 checksum
How to use checksums
f6f7f582cd587ebdfad6e7f6426ca3220b051d7adb41c824576851732843777a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 1, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page