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)
| File | Size | Uploaded | |
|---|---|---|---|
| minigun_soren_n-3.0.1.tar.gz | 59.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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}
|