Pytest Parameterized Test With Custom Id Function
Solution 1:
One way is to move your argvalues
to another variable and write your test like this:
import pytest
my_args = [
("2017.01", {"bills": "0,10", "shopping": "100,90", "Summe": "101,00"}),
("2017.02", {"bills": "20,00", "shopping": "10,00", "Summe": "30,00"})
]
@pytest.mark.parametrize(
argnames=('date', 'category_value'), argvalues=my_args,
ids=[i[0] for i in my_args]
)
def test_demo(date, category_value):
pass
Test execution:
$ pytest -v tests.py
================= test session starts =================
platform linux2 -- Python 2.7.12, pytest-3.2.1, py-1.4.34, pluggy-0.4.0 -- /home/kris/.virtualenvs/2/bin/python2
cachedir: .cache
rootdir: /home/kris/projects/tmp, inifile:
collected 2 items
tests.py::test_demo[2017.01] PASSED
tests.py::test_demo[2017.02] PASSED
============== 2 passed in 0.00 seconds ===============
I think it's not possible with a function (idfn
in your case), because if it's not generating label for an object the default pytest representation is used.
Check pytest site for details.
Solution 2:
Alternatively you can also use a list comprehension to generate your ids as follows:
import pytest
values = [
("2017.01", {"bills": "0,10", "shopping": "100,90", "Summe": "101,00"}),
("2017.02", {"bills": "20,00", "shopping": "10,00", "Summe": "30,00"})
]
value_ids = [e[0] for e in values]
@pytest.mark.parametrize('date,category_value', values, ids=value_ids
)
def test_demo(date, category_value):
pass
Assuming these tests are in test_file.py
at the root of your directory, if you run pytest test_file.py --co -q
, you will get the following output:
test_file.py::test_demo[2017.01]
test_file.py::test_demo[2017.02]
Solution 3:
Usually, when I want to be specific about test case being executing in the params I use named tuples as a workaround for the id funcion being executed once per param, that way a get a cleaner test description.
import pytest
from collections import namedtuple
TCase = namedtuple("TCase", "x,y,expected,description")
test_cases = [
TCase(10, 10, 20, "10 + 10 should be 20"),
TCase(1, 1, 2, "1 + 1 should be 2"),
]
def idfn(tc: TCase):
return tc.description
@pytest.mark.parametrize("tc", test_cases, ids=idfn)
def test_sum(tc):
assert tc.x + tc.y == tc.expected
Output:
example.py::test_sum[10 + 10 should be 20] PASSED
example.py::test_sum[1 + 1 should be 2] PASSED
So I would write your example as:
from collections import namedtuple
import pytest
TCase = namedtuple("TCase", "date,data")
my_args = [
TCase("2017.01", {"bills": "0,10", "shopping": "100,90", "Summe": "101,00"}),
TCase("2017.02", {"bills": "20,00", "shopping": "10,00", "Summe": "30,00"}),
]
@pytest.mark.parametrize("tc", my_args, ids=lambda tc: tc.date)
def test_demo(tc):
# Do something in here with tc.date and tc.data
pass
Output:
migration.py::test_demo[2017.01] PASSED
migration.py::test_demo[2017.02] PASSED
Post a Comment for "Pytest Parameterized Test With Custom Id Function"