Skip to content

Instantly share code, notes, and snippets.

@pfctdayelise
Last active October 26, 2018 15:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pfctdayelise/5719730 to your computer and use it in GitHub Desktop.
Save pfctdayelise/5719730 to your computer and use it in GitHub Desktop.
py.test - idparametrize mark, to easily parametrize tests with test ids/test names
def pytest_generate_tests(metafunc):
"""
If the test_ fn has a idparametrize mark, use it to create parametrized
tests with ids. Instead of giving a list of argvals (test values), it
should be a dict of test id strings -> tuple of test values
e.g.
@py.test.mark.idparametrize(('a', 'b'), {
'foo': (1, 2),
'bar': (3, 4),
})
Note tests will be ordered according to the test id string.
"""
idparametrize = getattr(metafunc.function, 'idparametrize', None)
if idparametrize:
argnames, testdata = idparametrize.args
ids, argvalues = zip(*sorted(testdata.items()))
metafunc.parametrize(argnames, argvalues, ids=ids)
$py.test test_foo.py -k groupby -v
========= test session starts ===========
platform linux3 -- Python 2.7.2 -- pytest-2.2.3 -- (...)
collected 1111 items
test_foo.py:1539: test_groupby[even sorted] PASSED
test_foo.py:1539: test_groupby[even unsorted] PASSED
test_foo.py:1539: test_groupby[under 5 sorted] PASSED
# note I am using py.test 2.2.3, I think in later versions it would just be
# pytest.mark not py.test.mark
from itertools import groupby
@py.test.mark.idparametrize(('data', 'keyFn', 'expected'), {
'even sorted': ([1, 3, 2, 4], lambda v: v % 2 == 0, [(False, [1, 3]),
(True, [2, 4])]),
'even unsorted': ([1, 2, 3, 4], lambda v: v % 2 == 0, [(False, [1]),
(True, [2]),
(False, [3]),
(True, [4])]),
'under 5 sorted': ([2, 4, 6, 8, 10, 12], lambda v: v < 5, [(True, [2, 4]),
(False, [6, 8, 10, 12])]),
})
def test_groupby(data, keyFn, expected):
result = [(k, list(g)) for k, g in groupby(data, key=keyFn)]
assert result == expected
@leohemsted
Copy link

leohemsted commented Oct 26, 2018

conftest.py line 14 can be refactored to idparametrize = metafunc.definition.get_closest_marker('idparametrize'), which avoids the warning:

RemovedInPytest4Warning: MarkInfo objects are deprecated as they contain merged marks which are hard to deal with correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment