diff --git a/_pytest/python.py b/_pytest/python.py index c5418b4d7..edc81e923 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -2480,7 +2480,7 @@ class FixtureDef: if hasattr(self, "cached_result"): config = self._fixturemanager.config if config.option.setuponly or config.option.setupplan: - self._log_fixture_stack('TEARDOWN') + self._show_fixture_action('TEARDOWN') if hasattr(self, "cached_param"): del self.cached_param del self.cached_result @@ -2533,22 +2533,24 @@ class FixtureDef: else: result = call_fixture_func(fixturefunc, request, kwargs) if config.option.setuponly or config.option.setupplan: - # We want to access the params of ids if they exist also in during - # the finish() method. if hasattr(request, 'param'): + # Save the fixture parameter so ._show_fixture_action() can + # display it now and during the teardown (in .finish()). if self.ids: - ind = self.params.index(request.param) - self.cached_param = self.ids[ind] + if callable(self.ids): + self.cached_param = self.ids(request.param) + else: + self.cached_param = self.ids[request.param_index] else: self.cached_param = request.param - self._log_fixture_stack('SETUP') + self._show_fixture_action('SETUP') except Exception: self.cached_result = (None, my_cache_key, sys.exc_info()) raise self.cached_result = (result, my_cache_key, None) return result - def _log_fixture_stack(self, what): + def _show_fixture_action(self, what): config = self._fixturemanager.config capman = config.pluginmanager.getplugin('capturemanager') if capman: diff --git a/testing/python/setup_only.py b/testing/python/setup_only.py index eef2857bb..e7403420b 100644 --- a/testing/python/setup_only.py +++ b/testing/python/setup_only.py @@ -159,6 +159,25 @@ def test_show_fixtures_with_parameter_ids(testdir, mode): ]) +def test_show_fixtures_with_parameter_ids_function(testdir, mode): + p = testdir.makepyfile(''' + import pytest + @pytest.fixture(params=['foo', 'bar'], ids=lambda p: p.upper()) + def foobar(): + pass + def test_foobar(foobar): + pass + ''') + + result = testdir.runpytest(mode, p) + assert result.ret == 0 + + result.stdout.fnmatch_lines([ + '*SETUP F foobar?FOO?', + '*SETUP F foobar?BAR?', + ]) + + def test_dynamic_fixture_request(testdir): p = testdir.makepyfile(''' import pytest