diff --git a/pytest_lazyfixture.py b/pytest_lazyfixture.py index 648c624..c156683 100644 --- a/pytest_lazyfixture.py +++ b/pytest_lazyfixture.py @@ -24,6 +24,13 @@ def pytest_runtest_setup(item): ) +def get_fixture_value(fname, request): + res = request.getfixturevalue(fname) + while is_lazy_fixture(res): + res = request.getfixturevalue(res.name) + return res + + def fillfixtures(_fillfixtures): def fill(request): item = request._pyfuncitem @@ -32,12 +39,12 @@ def fill(request): for fname in fixturenames: if fname not in item.funcargs and fname not in argnames: - item.funcargs[fname] = request.getfixturevalue(fname) + item.funcargs[fname] = get_fixture_value(fname, request) if hasattr(item, 'callspec'): for param, val in sorted_by_dependency(item.callspec.params, fixturenames): if is_lazy_fixture(val): - item.callspec.params[param] = request.getfixturevalue(val.name) + item.callspec.params[param] = get_fixture_value(val.name, request) _fillfixtures() return fill @@ -47,7 +54,16 @@ def pytest_runtest_call(item): if hasattr(item, 'funcargs'): for arg, val in item.funcargs.items(): if is_lazy_fixture(val): - item.funcargs[arg] = item._request.getfixturevalue(val.name) + item.funcargs[arg] = get_fixture_value(val.name, item._request) + + +def pytest_fixture_setup(fixturedef, request): + + for argname in fixturedef.argnames: + fixdef = request._get_active_fixturedef(argname) + result, arg_cache_key, exc = fixdef.cached_result + if is_lazy_fixture(result): + fixdef.cached_result = (get_fixture_value(result.name, request), arg_cache_key, exc) @pytest.hookimpl(hookwrapper=True) diff --git a/tests/test_lazyfixture.py b/tests/test_lazyfixture.py index ad67b2a..f85fae9 100644 --- a/tests/test_lazyfixture.py +++ b/tests/test_lazyfixture.py @@ -580,3 +580,59 @@ def test_sorted_by_dependency(params, expected_paths): ]) def test_sorted_argnames(params, fixturenames, expect_keys): assert list(_sorted_argnames(params, fixturenames)) == expect_keys + + +def test_lazy_fixture_nested_fixtures(testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture + def one(request): + return "SOME_VALUE" + @pytest.fixture + def two(request): + return "SOME_VALUE2" + @pytest.fixture(params=["one", "two"]) + def some_fixture1(request): + return pytest.lazy_fixture(request.param) + @pytest.fixture + def some_fixture2(some_fixture1): + return "NEW_" + some_fixture1 + def test_func(some_fixture2): + assert ((some_fixture2 == "NEW_SOME_VALUE") or (some_fixture2 == "NEW_SOME_VALUE2")) + """) + reprec = testdir.inline_run('-s') + reprec.assertoutcome(passed=2) + + +def test_lazy_fixture_nested_fixtures_in_parametrize(testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture + def one(request): + return "SOME_VALUE" + @pytest.fixture + def two(request): + return "SOME_VALUE2" + @pytest.fixture + def some_fixture_one(): + return pytest.lazy_fixture("one") + @pytest.fixture + def some_fixture_two(request): + return pytest.lazy_fixture("two") + @pytest.fixture + def some_nested_fixture_one(some_fixture_one): + return "NEW_" + some_fixture_one + @pytest.fixture + def some_nested_fixture_two(some_fixture_two): + return "NEW_" + some_fixture_two + @pytest.mark.parametrize('arg1,arg2,arg3', [ + ('val1', + pytest.lazy_fixture('some_nested_fixture_one'), + pytest.lazy_fixture('some_nested_fixture_two')), + ]) + def test_func(arg1, arg2, arg3): + assert (arg2 == "NEW_SOME_VALUE") + assert (arg3 == "NEW_SOME_VALUE2") + """) + reprec = testdir.inline_run('-s') + reprec.assertoutcome(passed=1)