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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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.