Skip to main content

GitHub PyPI PyPI - Downloads Discord GitHub Sponsors Documentation Status

Minigun

A QuickCheck-like library for property-based unit-testing of Python programs.

Minigun is inspired by QCheck, which in turn was inspired by QuickCheck. Both are libraries that provide implementations for performing property-based unit-testing; for OCaml and Haskell respectively.

If you would like a bit of motivation as to why you should use a QuickCheck-like system for testing your project, then I would recommend that you watch:

If you wish to learn more about the subject, I can recommend Jan Midtgaard's lecture materials; it is OCaml based but translates easily to other QuickCheck-like libraries for other languages.

Install

Minigun is currently only supported for Python >=3.12. It is distributed with pip and can be installed with the following example command:

pip install minigun-soren-n

Quick Start

Using the CLI (Recommended)

Create a test module in tests/ directory:

# tests/my_tests.py
from minigun import prop, conj

@prop("reversing a list twice gives the original")
def test_reverse(lst: list[int]):
    return list(reversed(list(reversed(lst)))) == lst

@prop("list length distributes over concatenation")
def test_length(xs: list[int], ys: list[int]):
    return len(xs + ys) == len(xs) + len(ys)

spec = conj(test_reverse, test_length)

Run your tests with time budget:

minigun --time-budget 30

Using as a Library

from minigun import prop, check

@prop("reversing a list twice gives the original")
def test_reverse(lst: list[int]):
    return list(reversed(list(reversed(lst)))) == lst

if __name__ == "__main__":
    success = check(test_reverse)
    exit(0 if success else 1)

Run directly:

python my_tests.py

Documentation

Full documentation and tutorials at Read The Docs.

Usage Guide

CLI Test Runner

# Run all tests in ./tests directory
minigun --time-budget 30

# Run tests from a different directory
minigun --time-budget 60 --test-dir my_tests

# Run specific test modules
minigun --time-budget 45 --modules my_tests other_tests

# List available test modules
minigun --list-modules

# Quiet mode (for CI/CD)
minigun --time-budget 60 --quiet

# JSON output (for automation)
minigun --time-budget 30 --json

# Reproduce a failing run
minigun --time-budget 30 --seed 42

The CLI discovers Python files in the test directory that export a module-level spec: Spec. When a run fails, the seed is printed so the exact run can be replayed with --seed.

Advanced: Manual Orchestrator Usage

For programmatic control, use the orchestrator directly:

# my_test_runner.py
from minigun.orchestrator import TestOrchestrator, OrchestrationConfig, TestModule
from minigun.specify import prop

@prop("your property")
def my_property(x: int):
    return x + 0 == x

if __name__ == "__main__":
    config = OrchestrationConfig(time_budget=30.0)

    modules = [TestModule("my_tests", my_property)]
    orchestrator = TestOrchestrator(config)
    success = orchestrator.execute_tests(modules)

    exit(0 if success else 1)

Writing Tests

Basic Properties

from minigun import prop

@prop("addition is commutative")
def test_add_commute(x: int, y: int):
    return x + y == y + x

Custom Generators

from minigun import prop, context, generate as g

@context(g.int_range(1, 100), g.int_range(1, 100))
@prop("division reverses multiplication")
def test_div(x: int, y: int):
    return (x * y) // y == x

Combining Properties

from minigun import prop, check, conj

@prop("property 1")
def test_1(x: int):
    return x + 0 == x

@prop("property 2")
def test_2(x: int):
    return x * 1 == x

# Check both together
success = check(conj(test_1, test_2))

FAQ

Q: What's a good time budget?

A: Start with 30-60 seconds for quick feedback. Use 2-5 minutes for thorough testing in CI/CD.

Q: How do I test larger input spaces?

A: Increase the time budget. The system automatically runs more test attempts when given more time.

Q: Can I customize test generation?

A: Yes, use the @context decorator with generators from minigun.generate. See documentation for details.

Q: How do I reproduce a failing run?

A: Every failing run prints its seed. Pass it back with minigun --seed <n> (or check(spec, seed=n)) to replay the exact same generation.

Real-World Usage

The following projects use Minigun for testing:

If you have used Minigun for testing a public project, please file an issue with a link to add it to this list.

Release files for minigun-soren-n 3.0.1

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

Source distribution (sdist)

Source distribution for minigun-soren-n 3.0.1
File Size Uploaded
minigun_soren_n-3.0.1.tar.gz 59.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for minigun-soren-n 3.0.1
File Interpreter ABI Platform
minigun_soren_n-3.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 120.6 kB

Release files / minigun_soren_n-3.0.1.tar.gz

Download URL minigun_soren_n-3.0.1.tar.gz
Size 59.1 kB
Tags Source
SHA-256 checksum
How to use checksums
10f289079b7a5a5f220c37c4f304f76412e3dd2533c48028db941acdc9da1598
BLAKE2b-256 checksum
How to use checksums
be826d9ea2ffa93d7bd5bf3a21cb439da41c3ee39a40a1ec3d15eb90ac52f724
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / minigun_soren_n-3.0.1-py3-none-any.whl

Download URL minigun_soren_n-3.0.1-py3-none-any.whl
Size 61.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f7e04415a1c7ddad3201c78f1a4ea47cf229db1301df7631e1744a589707760d
BLAKE2b-256 checksum
How to use checksums
ef1dae082e004ffa3b808fddbdda261c6824ba8bd5c7be14650a0ad658143a66
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

4.0.0

2 release files

This release

3.0.1 This release

2 release files

3.0.0

2 release files

2.5.0

2 release files

2.4.3

2 release files

2.4.2

2 release files

2.4.1

2 release files

2.4.0

2 release files

2.3.0

2 release files

2.2.5

2 release files

2.2.4

2 release files

2.2.3

2 release files

2.2.2

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.0.0

2 release files

0.4.12

1 release file

0.4.10

1 release file

0.4.9

1 release file

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