Skip to main content

Rust powered pytest-compatible runner

Project description

rustest logo

Rustest (pronounced like Russ-Test) is a Rust-powered test runner that aims to provide the most common pytest ergonomics with a focus on raw performance. Get massive speedups (8.5× average, up to 19× faster) with familiar syntax and minimal setup.

📚 Full Documentation | Getting Started | User Guide | API Reference

Why rustest?

  • 🚀 8.5× average speedup over pytest on the synthetic benchmark matrix (peaking at 19× on 5k-test suites)
  • ✅ Familiar @fixture, @parametrize, @skip, and @mark decorators
  • 🔄 Built-in async support with @mark.asyncio (like pytest-asyncio)
  • 🔍 Automatic test discovery (test_*.py and *_test.py files)
  • 📝 Built-in markdown code block testing (like pytest-codeblocks, but faster)
  • 🎯 Simple, clean API—if you know pytest, you already know rustest
  • 🧮 Built-in approx() helper for tolerant numeric comparisons
  • 🪤 raises() context manager for precise exception assertions
  • 📦 Easy installation with pip or uv
  • ⚡ Low-overhead execution keeps small suites feeling instant

Performance

Rustest is designed for speed. The new benchmark matrix generates identical pytest and rustest suites ranging from 1 to 5,000 tests and runs each command five times. Rustest delivers an 8.5× average speedup and reaches 19× faster execution on the largest suite:

Test Count pytest (mean) rustest (mean) Speedup pytest tests/s rustest tests/s
1 0.428s 0.116s 3.68x 2.3 8.6
5 0.428s 0.120s 3.56x 11.7 41.6
20 0.451s 0.116s 3.88x 44.3 171.7
100 0.656s 0.133s 4.93x 152.4 751.1
500 1.206s 0.146s 8.29x 414.4 3436.1
1,000 1.854s 0.171s 10.83x 539.4 5839.4
2,000 3.343s 0.243s 13.74x 598.3 8219.9
5,000 7.811s 0.403s 19.37x 640.2 12399.7

What speedup should you expect?

  • Tiny suites (≤20 tests): Expect ~3–4× faster runs. Startup costs dominate here, so both runners feel instant, but rustest still trims a few hundred milliseconds on every run.
  • Growing suites (≈100–500 tests): Expect ~5–8× faster execution. Once you have a few dozen files, rustest's lean discovery and fixture orchestration start to compound.
  • Large suites (≥1,000 tests): Expect ~11–19× faster runs. Bigger suites amortize startup overhead entirely, letting rustest's Rust core stretch its legs and deliver order-of-magnitude gains.

Highlights:

  • 8.5× average speedup across the matrix (geometric mean 7.0×)
  • 16.2× weighted speedup when weighting by the number of executed tests
  • 1.45s total runtime for rustest vs 16.18s for pytest across all suites

Reproduce the matrix locally:

python3 profile_tests.py --runs 5
python3 generate_comparison.py

Real-world integration suite (~200 tests)

Our integration suite remains a great proxy for day-to-day use and still shows a ~2.1× wall-clock speedup:

Test Runner Wall Clock Speedup Command
pytest 1.33–1.59s 1.0x (baseline) pytest tests/ examples/tests/ -q
rustest 0.69–0.70s ~2.1x faster python -m rustest tests/ examples/tests/

Large parametrized stress test

With 10,000 parametrized invocations:

Test Runner Avg. Wall Clock Speedup Command
pytest 9.72s 1.0x pytest benchmarks/test_large_parametrize.py -q
rustest 0.41s ~24x faster python -m rustest benchmarks/test_large_parametrize.py

📊 View Detailed Performance Analysis →

Installation

Rustest supports Python 3.10 through 3.14.

# Using pip
pip install rustest

# Using uv
uv add rustest

📖 Installation Guide →

Quick Start

1. Write Your Tests

Create a file test_math.py:

from rustest import fixture, parametrize, mark, approx, raises
import asyncio

@fixture
def numbers() -> list[int]:
    return [1, 2, 3, 4, 5]

def test_sum(numbers: list[int]) -> None:
    assert sum(numbers) == approx(15)

@parametrize("value,expected", [(2, 4), (3, 9), (4, 16)])
def test_square(value: int, expected: int) -> None:
    assert value ** 2 == expected

@mark.slow
def test_expensive_operation() -> None:
    result = sum(range(1000000))
    assert result > 0

@mark.asyncio
async def test_async_operation() -> None:
    # Example async operation
    await asyncio.sleep(0.001)
    result = 42
    assert result == 42

def test_division_by_zero() -> None:
    with raises(ZeroDivisionError, match="division by zero"):
        1 / 0

2. Run Your Tests

# Run all tests
rustest

# Run specific tests
rustest tests/

# Filter by test name pattern
rustest -k "test_sum"

# Filter by marks
rustest -m "slow"                    # Run only slow tests
rustest -m "not slow"                # Skip slow tests
rustest -m "slow and integration"    # Run tests with both marks

# Rerun only failed tests
rustest --lf                         # Last failed only
rustest --ff                         # Failed first, then all others

# Exit on first failure
rustest -x                           # Fail fast

# Combine options
rustest --ff -x                      # Run failed tests first, stop on first failure

# Show output during execution
rustest --no-capture

📖 Full Quick Start Guide →

Documentation

📚 Full Documentation

Getting Started

User Guide

API Reference

Advanced Topics

Feature Comparison with pytest

Rustest implements the 20% of pytest features that cover 80% of use cases, with a focus on raw speed and simplicity.

📋 View Full Feature Comparison →

Supported: Fixtures, parametrization, marks, test classes, conftest.py, markdown testing 🚧 Planned: Parallel execution, mark filtering, JUnit XML output ❌ Not Planned: Plugins, hooks, custom collectors (keeps rustest simple)

Contributing

We welcome contributions! See the Development Guide for setup instructions.

Quick reference:

# Setup
git clone https://github.com/Apex-Engineers-Inc/rustest.git
cd rustest
uv sync --all-extras
uv run maturin develop

# Run tests
uv run poe pytests  # Python tests
cargo test          # Rust tests

# Format and lint
uv run pre-commit install  # One-time setup
git commit -m "message"    # Pre-commit hooks run automatically

License

rustest is distributed under the terms of the MIT license. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rustest-0.8.2.tar.gz (236.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rustest-0.8.2-cp313-cp313-win_amd64.whl (752.6 kB view details)

Uploaded CPython 3.13Windows x86-64

rustest-0.8.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (916.7 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

rustest-0.8.2-cp313-cp313-macosx_11_0_arm64.whl (838.8 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

rustest-0.8.2-cp312-cp312-win_amd64.whl (752.8 kB view details)

Uploaded CPython 3.12Windows x86-64

rustest-0.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (916.7 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

rustest-0.8.2-cp312-cp312-macosx_11_0_arm64.whl (838.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

rustest-0.8.2-cp311-cp311-win_amd64.whl (753.2 kB view details)

Uploaded CPython 3.11Windows x86-64

rustest-0.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (917.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

rustest-0.8.2-cp311-cp311-macosx_11_0_arm64.whl (839.2 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

rustest-0.8.2-cp310-cp310-win_amd64.whl (753.3 kB view details)

Uploaded CPython 3.10Windows x86-64

rustest-0.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (918.2 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

rustest-0.8.2-cp310-cp310-macosx_11_0_arm64.whl (839.4 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file rustest-0.8.2.tar.gz.

File metadata

  • Download URL: rustest-0.8.2.tar.gz
  • Upload date:
  • Size: 236.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.8

File hashes

Hashes for rustest-0.8.2.tar.gz
Algorithm Hash digest
SHA256 5e1068dccafaa436666ea2a88f96adc727a79b9ecb248827e430fe135784195b
MD5 ae783b8995fd25d80b22d50658af075a
BLAKE2b-256 f2afb9995056e79221df28c8b85ec00f9687ab2275aae85871587547956f3ced

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 70ce31405c1317a2fa9085e3c56de83e324e89d8f65936dedd1bd0c53dce434a
MD5 aae6764466332bb7c9f468868f1e41b8
BLAKE2b-256 6fdc225a146d824c60a7bc486c8f62c19dd8c413a5336bc3a2c9be9585c1bcae

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2f6ae2535c20af01e929c3a52ded5ef5a0cb9efd6699bc6ad8123f747be4c1dc
MD5 65c494d5f0f8310aacfb52b46e38fae5
BLAKE2b-256 11efd2b460a56f7797a587b48c9ba705fdca2a3da865d76690e8a8dcb1b5d015

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4d2929978021f040c720ff4ef4120c2ed01d684776c726a5d43329002010530c
MD5 834dee4bbfa206f2f1a31ef4f6061a18
BLAKE2b-256 bdeca41799f4aff93ab99021612f6a54001d69d7563a10ac5b7ddf9f5c2ed816

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 7649f24a4d3e1d667c5d6baac08fb81faf52483cca421365623d908542fd34e2
MD5 1f6932a085f8f79918810744d014b4f9
BLAKE2b-256 efbe1cc58308f6efb737a7a18ba81a9b01742819002645d24a2ba42d1e833e94

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1c3ee352eccac87689590103278cb6800c932cf8180b43febe72675e8a96547b
MD5 97a26d6b72e6e178f636d2e6f2bd3ee4
BLAKE2b-256 399be7cb70d09739c2d874320c4f53d086c7d4a5d7e5e9ebce73d64522f85c76

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e7e9af21cd6bc127c2de84dd04e543828f94f15bae25cfec9c535f2a0dea6bef
MD5 b7ec7d7c6c14da1f5d0fa606a982549c
BLAKE2b-256 566c9cce22af8527f6a32b323a6163ab15c93e0f2df295726430a4c50728d3de

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 852c2d1560914e478df9e2e9b895800003baba109305dbb4e1dba5d13b31da4a
MD5 6f9b757561c836c69117790cfa76d8d2
BLAKE2b-256 9d4d896dc1314d1a0f6c2dfe224f66ce1f1d0f77e3eb248bc396b7f963d49a12

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 012069741147a501764e2500e3989752a3fe01b9a5f2a329636e34094d6ce9a5
MD5 12628a5da201a19b60a4096a90c506fc
BLAKE2b-256 121d18d10a356289eb5c5ccc952c15f68b6f82fdcd97d21a201460c08a1a9caa

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ba8a53ef34c819015f4c023512dfcdc967f793806705c7342b10a10ebcbf5d6d
MD5 2d900187d9e83a86bf35e9e28b903b96
BLAKE2b-256 4579d77b58cabb542a937705a64f69897810f41f1d1dab6668fec8d72fc01b1c

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 b3bf6efe58bbd734120695df40b914dce005c50e55143779acd842ece01f9c1e
MD5 2fba4e9e6da2f43ed23067b6b14e93c1
BLAKE2b-256 c3c1310c773f6cc399ae1db6eac25e89827607f7a0d691676ea555ad4bea1f5f

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9c7c15c924cd5445a365b9a6ee89842bf317659ad0027f099a33e982dc6f294d
MD5 de94fae5b0755b3fdf60bafd1b34f865
BLAKE2b-256 b8165177eff794db404431342468ed9e596c8a82126f50e16ce8a77a714757a9

See more details on using hashes here.

File details

Details for the file rustest-0.8.2-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustest-0.8.2-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6541f773a7833082300a732b6a00481b90413632959171ce6ad4173f8735e883
MD5 c676f606871594fe3dcf9ee0cc8fe2fb
BLAKE2b-256 7247f223325f6e707c7d6d85ecf6be4cf38070f1ae0ec0a63f27ec28cca7d854

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page