From 806ea8ac5cebecb4b01e588a92249f1929243c20 Mon Sep 17 00:00:00 2001 From: Rolf Krahl Date: Sun, 27 Aug 2017 19:55:44 +0200 Subject: [PATCH] Add examples how to depend on all instances of a parametrized test. Related to Issue #9. --- doc/examples/all_params.py | 55 ++++++++++++++++++++++++++++++++++++++ doc/src/advanced.rst | 27 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 doc/examples/all_params.py diff --git a/doc/examples/all_params.py b/doc/examples/all_params.py new file mode 100644 index 0000000..4c6edb8 --- /dev/null +++ b/doc/examples/all_params.py @@ -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 diff --git a/doc/src/advanced.rst b/doc/src/advanced.rst index a788fab..8279c60 100644 --- a/doc/src/advanced.rst +++ b/doc/src/advanced.rst @@ -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.