Move fixtures.py::add_funcarg_pseudo_fixture_def
to Metafunc.parametrize
by sadra-barikbin · Pull Request #11220 · pytest-dev/pytest (original) (raw)
After reading your comment and looking more closely at the issue_519.py file, I think I understood some things:
First, I'm really not used to the pytest_generate_tests
hook, so I rewrote the test using pytest.mark.parametrize
. I also changed some of the names to make things clearer to me:
Rewritten issue_519.py
import pprint from typing import List from typing import Tuple
import pytest
@pytest.fixture(scope="session") def checked_order(): order: List[Tuple[str, str, str]] = []
yield order
pprint.pprint(order)
@pytest.fixture(scope="module") def fixmod(request, a, checked_order): checked_order.append((request.node.name, "fixmod", a)) yield "fixmod-" + a
@pytest.fixture(scope="function") def fixfun(request, fixmod, b, checked_order): checked_order.append((request.node.name, "fixfun", b)) yield "fixfun-" + b + fixmod
@pytest.mark.parametrize("b", ["b1", "b2"], scope="function") @pytest.mark.parametrize("a", ["a1", "a2"], scope="module") def test_one(fixfun, request): print() # print(request._pyfuncitem.nodeid, request._pyfuncitem.callspec)
@pytest.mark.parametrize("b", ["b1", "b2"], scope="function") @pytest.mark.parametrize("a", ["a1", "a2"], scope="module") def test_two(fixfun, request): print() # print(request._pyfuncitem.nodeid, request._pyfuncitem.callspec)
This made me realize that the apparent niceness of the previous ordering, which orders test_one[arg1v1-arg2v1]
next to test_two[arg1v1-arg2v1]
, thus saving a setup, is pretty arbitrary. This can be shown by making the values of the function-scoped parameter (arg2
/b
) different in test_one
and test_two
:
-@pytest.mark.parametrize("b", ["b1", "b2"], scope="function") +@pytest.mark.parametrize("b", ["b11", "b12"], scope="function") @pytest.mark.parametrize("a", ["a1", "a2"], scope="module") def test_one(fixfun, request): print() # print(request._pyfuncitem.nodeid, request._pyfuncitem.callspec)
-@pytest.mark.parametrize("b", ["b1", "b2"], scope="function") +@pytest.mark.parametrize("b", ["b21", "b22"], scope="function") @pytest.mark.parametrize("a", ["a1", "a2"], scope="module") def test_two(fixfun, request): print()
The ordering stays the same, which now doesn't make sense.
I also figured that the entire param_index
thing was much more useful/natural in the pre-parametrize
times, when only pytest_generate_tests
/metafunc
was used for parametrizing. With pytest_generate_tests
you often use the same parameter set for different tests, as is done in the issue_519.py file. But with parametrize
, which is mostly done for a single test-function only, it is much less common, I think.