Skip to content

Commit

Permalink
Add examples how to depend on all instances of a parametrized test.
Browse files Browse the repository at this point in the history
Related to Issue #9.
  • Loading branch information
RKrahl committed Aug 27, 2017
1 parent 35fe28a commit 806ea8a
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
55 changes: 55 additions & 0 deletions doc/examples/all_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import pytest

def instances(name, params):
def vstr(val):
if isinstance(val, (list, tuple)):
return "-".join([str(v) for v in val])
else:
return str(val)
return ["%s[%s]" % (name, vstr(v)) for v in params]


params_a = range(17)

@pytest.mark.parametrize("x", params_a)
@pytest.mark.dependency()
def test_a(x):
if x == 13:
pytest.xfail("deliberate fail")
assert False
else:
pass

@pytest.mark.dependency(depends=instances("test_a", params_a))
def test_b():
pass

params_c = zip(range(0,8,2), range(2,6))

@pytest.mark.parametrize("x,y", params_c)
@pytest.mark.dependency()
def test_c(x, y):
if x > y:
pytest.xfail("deliberate fail")
assert False
else:
pass

@pytest.mark.dependency(depends=instances("test_c", params_c))
def test_d():
pass

params_e = ['abc', 'def']

@pytest.mark.parametrize("s", params_e)
@pytest.mark.dependency()
def test_e(s):
if 'e' in s:
pytest.xfail("deliberate fail")
assert False
else:
pass

@pytest.mark.dependency(depends=instances("test_e", params_e))
def test_f():
pass
27 changes: 27 additions & 0 deletions doc/src/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,30 @@ In this example, both `test_b[7]` and `test_c[7]` are skipped, because
`test_a[7]` deliberately fails.

.. __: https://docs.pytest.org/en/latest/fixture.html#automatic-grouping-of-tests-by-fixture-instances

Depend on all instances of a parametrized test at once
------------------------------------------------------

If a test depends on a all instances of a parametrized test at once,
listing all of them in the :func:`pytest.mark.dependency` marker
explicitly might not be the best solution. But you can dynamically
compile these lists from the parameter values, as in the following
example:

.. literalinclude:: ../examples/all_params.py

Here, `test_b`, `test_d`, and `test_f` will be skipped because they
depend on all instances of `test_a`, `test_c`, and `test_e`
respectively, but `test_a[13]`, `test_c[6-5]`, and `test_e[def]` fail.
The list of the test instances is compiled in the helper function
`instances()`.

Unfortunately you need knowledge how pytest encodes parameter values
in test instance names to write this helper function. Note in
particular how lists of parameter values are compiled into one single
string in the case of multi parameter tests. But also note that this
example of the `instances()` helper will only work for simple cases.
It requires the parameter values to be scalars that can easily be
converted to strings. And it will fail if the same list of parameters
is passed to the same test more then once, because then, pytest will
add an index to the name to disambiguate the parameter values.

0 comments on commit 806ea8a

Please sign in to comment.