Skip to main content

wouldcatch

Your tests pass. Would they catch a bug?
wouldcatch plants small bugs in the lines you just changed, runs your tests, and shows the ones nobody noticed.

CI Python 3.10+ Zero dependencies MIT license

wouldcatch finds 3 bugs the tests miss, then 0 after one more test

pipx install git+https://github.com/Sahil-u07/wouldcatch
cd your-repo && wouldcatch

On Windows without pipx: py -m pip install git+https://github.com/Sahil-u07/wouldcatch, then run wouldcatch from PowerShell or Windows Terminal.

No config. No dependencies. Works on any git repo with pytest (or any test command).

Green tests can still miss bugs

You add a member discount and write two tests. Every line runs. Everything passes.

def discount(price, is_member):
    if is_member and price >= 100:
        return price - 10
    return price

def test_member():
    assert discount(200, True) == 190

def test_guest():
    assert discount(50, False) == 50
$ wouldcatch
  MISSED  shop.py:2  `and` -> `or`
  MISSED  shop.py:2  `>=` -> `>`
  MISSED  shop.py:2  `100` -> `101`

4/7 caught. 3 bug(s) your tests would not notice.

Each MISSED line is a bug someone could ship and your suite would stay green:

  • >= becoming > means a member spending exactly 100 gets no discount. No test checks 100.
  • and becoming or gives every guest over 100 the discount. No test has a guest over 100.

Add assert discount(100, True) == 90 and assert discount(200, False) == 200, run it again, and you get 7/7 caught.

Coverage can't tell you this. It counts which lines ran, not whether a test would fail if they were wrong.

Why only the diff

Mutation testing is the honest way to grade a test suite, but running it on a whole project can take hours, so almost nobody does. wouldcatch only mutates the lines in your git diff. A normal change gives 5 to 30 mutants, so it finishes while you're still writing the commit message.

Line coverage Whole-project mutation testing wouldcatch
Tells you a test would fail on a bug no yes yes
Time on a typical change seconds minutes to hours seconds to a few minutes
Setup plugin config files none
Output a percentage a report on everything the exact lines to test

How it works

  1. Reads git diff to find the Python lines you changed. Test files are skipped.
  2. Makes one small change at a time on those lines: < to <=, == to !=, and to or, + to -, True to False, 100 to 101, a return value to None, an if flipped.
  3. Runs your tests after each change. Tests still green means that bug would have gotten through.
  4. Puts the file back byte for byte (CRLF included) after every run, even on Ctrl+C or a killed process.

Usage

wouldcatch                                  # uncommitted changes, or the last commit if the tree is clean
wouldcatch --base main                      # everything on this branch since main
wouldcatch --cmd "pytest tests/unit -x -q"  # run only the tests that matter
wouldcatch --json                           # machine-readable output for scripts and agents
wouldcatch --all                            # list caught mutants too
wouldcatch --max 100                        # try more mutants (default 50)

Exit codes: 0 all caught, 1 something missed, 2 setup problem (not a git repo, tests already failing).

Skip a line on purpose:

RETRY_DELAY = 5  # wouldcatch: ignore

Use it everywhere

GitHub Actions, on every pull request:

- uses: actions/checkout@v5
  with:
    fetch-depth: 0
- run: pip install git+https://github.com/Sahil-u07/wouldcatch pytest
- run: wouldcatch --base origin/${{ github.base_ref }}

pre-commit, before every commit (with wouldcatch installed in your project environment):

- repo: https://github.com/Sahil-u07/wouldcatch
  rev: main
  hooks:
    - id: wouldcatch

AI coding agents. Agents are good at writing tests that pass and bad at writing tests that check anything. wouldcatch gives them a concrete target: make every MISSED line fail.

  • Claude Code: copy skills/wouldcatch into .claude/skills/ in your project.
  • Any other agent: add this to AGENTS.md:
After changing Python code, run `wouldcatch --json`. For every mutant with
"status": "missed", add a test that fails for that change. Re-run until none are missed.
Never change the source code to make a mutant go away.

FAQ

Will it mess up my files? It edits one file at a time and restores it right after. If the process dies mid-run, the next run restores the file from .wouldcatch-backup.json before doing anything else.

My test suite is slow. Each mutant is one run of your test command. Point --cmd at the relevant tests and use -x so pytest stops at the first failure.

A mutant can't be caught, the code really doesn't care. That happens (a log interval, a cache size). Mark the line # wouldcatch: ignore.

JavaScript, TypeScript, Go? Python today. The git part is language-neutral; JS/TS is next. Join the discussion.

Contributing

New mutations are small, self-contained PRs. Start with a good first issue and see CONTRIBUTING.md.

If wouldcatch found a bug your tests missed, a star helps other people find it.

License

MIT

Metadata

Release files for wouldcatch 0.1.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 wouldcatch 0.1.0
File Size Uploaded Provenance Actions
wouldcatch-0.1.0.tar.gz 14.2 kB With provenance Details for wouldcatch-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for wouldcatch 0.1.0
File Interpreter ABI Platform Actions
wouldcatch-0.1.0-py3-none-any.whl Python 3 none any Details for wouldcatch-0.1.0-py3-none-any.whl

Total release size: 25.2 kB

Release files / wouldcatch-0.1.0.tar.gz

Download URL wouldcatch-0.1.0.tar.gz
Size 14.2 kB
Tags Source
SHA-256 checksum
How to use checksums
18e26e6f7b27fa270b8b386516ab55cbc6fb4cef9af607c542b4ff634c97e48c
BLAKE2b-256 checksum
How to use checksums
8f0ad464b8c88b2cb640bcc202978a5d62ce9e5f5fbffed12d63979e88de6e15
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 11, 2026.

Transparency log

Release files / wouldcatch-0.1.0-py3-none-any.whl

Download URL wouldcatch-0.1.0-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2cdfb3f9f6a9c44eeb20adbd3a008c7375fa825d3a4bfbc6e683aa44b2813341
BLAKE2b-256 checksum
How to use checksums
08fed66e5392ae0cd4deeb416ff14431abac63c62f34ee4a1389b682ccb10824
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 11, 2026.

Transparency log

Security for wouldcatch 0.1.0

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for wouldcatch-0.1.0.tar.gz

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 Nov 11, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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