Skip to main content

pytest-funparam

pytest-funparam makes it easy to write parametrized tests.

Unlike pytest.mark.parametrize, pytest-funparam:

  • includes the failing parameter in pytest tracebacks;

  • enables static type checking of parameters; and

  • keeps parameters and assertions closer together.

Installation

You can install “pytest-funparam” via pip from PyPI:

$ pip install pytest-funparam

Usage

Inside a test function, decorate a function with the funparam fixture:

def test_addition(funparam):
    @funparam
    def verify_sum(a, b, expected):
        assert a + b == expected

    verify_sum(1, 2, 3)
    verify_sum(2, 2, 5)  # OOPS!
    verify_sum(4, 2, 6)

And run pytest:

$ pytest
============================= test session starts ==============================
collected 3 items

test_readme.py .F.                                                       [100%]

=================================== FAILURES ===================================
_______________________________ test_addition[1] _______________________________

    def test_addition(funparam):
        @funparam
        def verify_sum(a, b, expected):
            assert a + b == expected

        verify_sum(1, 2, 3)
>       verify_sum(2, 2, 5)  # OOPS!

test_readme.py:7:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

a = 2, b = 2, expected = 5

    @funparam
    def verify_sum(a, b, expected):
>       assert a + b == expected
E       assert (2 + 2) == 5

test_readme.py:4: AssertionError
========================= 1 failed, 2 passed in 0.03s ==========================

The test_addition test case was split into 3 tests, one for each verify_sum call.

Because funparam is parametrizing the test calls, it even works with commands like pytest --last-failed:

$ pytest --last-failed
============================= test session starts ==============================
collected 1 item

test_readme.py F                                                         [100%]

=================================== FAILURES ===================================
_______________________________ test_addition[1] _______________________________

    def test_addition(funparam):
        @funparam
        def verify_sum(a, b, expected):
            assert a + b == expected

        verify_sum(1, 2, 3)
>       verify_sum(2, 2, 5)  # OOPS!

test_readme.py:7:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

a = 2, b = 2, expected = 5

    @funparam
    def verify_sum(a, b, expected):
>       assert a + b == expected
E       assert (2 + 2) == 5

test_readme.py:4: AssertionError
============================== 1 failed in 0.01s ===============================

Markers

Mark tests by using the .marks() method of your funparam function.

import pytest

def test_addition(funparam):
    @funparam
    def verify_sum(a, b, expected):
        assert a + b == expected

    verify_sum(1, 2, 3)
    verify_sum.marks(pytest.mark.skip)(2, 2, 5)
    verify_sum(4, 2, 6)
$ pytest
============================= test session starts ==============================
collected 3 items

test_readme.py .s.                                                       [100%]

========================= 2 passed, 1 skipped in 0.01s =========================

Test IDs

Similarly, add an id to a test using the .id() method of your funparam function:

def test_addition(funparam):
    @funparam
    def verify_sum(a, b, expected):
        assert a + b == expected

    verify_sum.id("one and two")(1, 2, 3)
    verify_sum.id("two and two")(2, 2, 5)
    verify_sum.id("four and two")(4, 2, 6)
$ pytest --collect-only
============================= test session starts ==============================
collected 3 items

<Module test_readme.py>
  <Function test_addition[one and two]>
  <Function test_addition[two and two]>
  <Function test_addition[four and two]>

========================== 3 tests collected in 0.01s ==========================

You can also use the shorthand for assigning an id. (It does the same thing as calling .id().)

def test_addition(funparam):
    @funparam
    def verify_sum(a, b, expected):
        assert a + b == expected

    verify_sum["one and two"](1, 2, 3)
    verify_sum["two and two"](2, 2, 5)
    verify_sum["four and two"](4, 2, 6)
$ pytest --collect-only
============================= test session starts ==============================
collected 3 items

<Module test_readme.py>
  <Function test_addition[one and two]>
  <Function test_addition[two and two]>
  <Function test_addition[four and two]>

========================== 3 tests collected in 0.01s ==========================

Type Annotations

pytest-funparam has full type annotations. The funparam fixture returns a FunparamFixture object. You can import it from pytest_funparam:

import pytest
from pytest_funparam import FunparamFixture

def test_addition(funparam: FunparamFixture):

    @funparam
    def verify_sum(a: int, b: int , expected: int):
        assert a + b == expected

    # These are valid
    verify_sum(1, 2, 3)
    verify_sum['it accommodates ids'](2, 2, 4)
    # Marks work too!
    verify_sum.marks(pytest.mark.xfail)(2, 2, 9)

    # This will be marked as invalid (since it's not an int)
    verify_sum(1, '2', 3)

    # Using id/marks will still preserve the function's typing.
    verify_sum['should be an int'](1, 2, '3')
$ mypy
test_readme.py:17: error: Argument 2 to "verify_sum" has incompatible type "str"; expected "int"
test_readme.py:20: error: Argument 3 to "verify_sum" has incompatible type "str"; expected "int"
Found 2 errors in 1 file (checked 1 source file)

License

Distributed under the terms of the MIT license, “pytest-funparam” is free and open source software

Issues

If you encounter any problems, please file an issue along with a detailed description.

Metadata

Release files for pytest-funparam 0.3.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-funparam 0.3.0
File Size Uploaded Provenance Actions
pytest-funparam-0.3.0.tar.gz 14.8 kB Without provenance Details for pytest-funparam-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pytest-funparam 0.3.0
File Interpreter ABI Platform Actions
pytest_funparam-0.3.0-py3-none-any.whl Python 3 none any Details for pytest_funparam-0.3.0-py3-none-any.whl

Total release size: 21.7 kB

Release files / pytest-funparam-0.3.0.tar.gz

Download URL pytest-funparam-0.3.0.tar.gz
Size 14.8 kB
Tags Source
SHA-256 checksum
How to use checksums
01011c123136b95455915af4a6381447e7127b2c4924574f37d4add1076fbb1c
BLAKE2b-256 checksum
How to use checksums
6435642daac19de80bd7b9d33118fa541acaa86b24ad351353b652528697d768
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.25.1

Release files / pytest_funparam-0.3.0-py3-none-any.whl

Download URL pytest_funparam-0.3.0-py3-none-any.whl
Size 6.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
75f18aaf1e1452424a68da4752e3828f37d2242d885151c51e6a036d73ecc383
BLAKE2b-256 checksum
How to use checksums
76ce2685cc20555a958c9a9a35746a2de64e9112ac5c719bbd9088f472544680
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.25.1

Security for pytest-funparam 0.3.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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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