@@ -688,3 +688,70 @@ For example:
688688 In the example above, the first three test cases should run without any
689689exceptions, while the fourth should raise a ``ZeroDivisionError `` exception,
690690which is expected by pytest.
691+
692+ .. _`parametrize_dependent` :
693+
694+ Adding parameters depending on previous parametrizations
695+ --------------------------------------------------------------------
696+
697+ By default, :hook: `pytest_generate_tests ` hooks and
698+ :ref: `pytest.mark.parametrize <pytest.mark.parametrize ref >` generate
699+ a Cartesian product of parameter sets in case of multiple parametrizations,
700+ see :ref: `parametrize-basics ` for some examples.
701+
702+ Sometimes, values of some parameters need to be generated based on values
703+ of previous parameters or based on their associated marks.
704+
705+ In such cases ``parametrize `` can be passed a callable for ``argvalues ``,
706+ which will decide how to further parametrize each test instance:
707+
708+ .. code-block :: python
709+
710+ # content of test_parametrize_dependent.py
711+ def pytest_generate_tests (metafunc : pytest.Metafunc):
712+ if " bar" in metafunc.fixturenames:
713+ # parametrize "bar" arg based on "bar_params" mark
714+ base_bar_marks = list (metafunc.definition.iter_markers(" bar_params" ))
715+
716+ def gen_params (callspec : pytest.CallSpec):
717+ # collect all marks
718+ bar_marks = base_bar_marks + [
719+ mark for mark in callspec.marks if mark.name == " bar_params"
720+ ]
721+ # collect all args from all marks
722+ return [arg for mark in bar_marks for arg in mark.args]
723+
724+ metafunc.parametrize(" bar" , gen_params)
725+
726+
727+ @pytest.mark.bar_params (" x" )
728+ @pytest.mark.parametrize (
729+ " foo" ,
730+ [
731+ " a" ,
732+ pytest.param(" b" , marks = [pytest.mark.bar_params(" y" , " z" )]),
733+ pytest.param(" c" , marks = [pytest.mark.bar_params(" w" )]),
734+ ],
735+ )
736+ def test_function (foo , bar ):
737+ pass
738+
739+ Running ``pytest `` with verbose mode outputs:
740+
741+ .. code-block :: pytest
742+
743+ $ pytest -v
744+ =========================== test session starts ============================
745+ platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python
746+ cachedir: .pytest_cache
747+ rootdir: /home/sweet/project
748+ collecting ... collected 6 items
749+
750+ test_parametrize_dependent.py::test_function[a-x] PASSED [ 16%]
751+ test_parametrize_dependent.py::test_function[b-x] PASSED [ 33%]
752+ test_parametrize_dependent.py::test_function[b-y] PASSED [ 50%]
753+ test_parametrize_dependent.py::test_function[b-z] PASSED [ 66%]
754+ test_parametrize_dependent.py::test_function[c-x] PASSED [ 83%]
755+ test_parametrize_dependent.py::test_function[c-w] PASSED [100%]
756+
757+ ============================ 6 passed in 0.12s =============================
0 commit comments