Improve error message when a recursive dependency between fixtures is detected

Fix #2909
This commit is contained in:
Bruno Oliveira 2018-10-20 09:44:42 -03:00
parent b0eed7b56c
commit 02ae7d8531
4 changed files with 33 additions and 5 deletions

View File

@ -0,0 +1 @@
Improve error message when a recursive dependency between fixtures is detected.

View File

@ -762,14 +762,19 @@ class FixtureLookupError(LookupError):
if msg is None: if msg is None:
fm = self.request._fixturemanager fm = self.request._fixturemanager
available = [] available = set()
parentid = self.request._pyfuncitem.parent.nodeid parentid = self.request._pyfuncitem.parent.nodeid
for name, fixturedefs in fm._arg2fixturedefs.items(): for name, fixturedefs in fm._arg2fixturedefs.items():
faclist = list(fm._matchfactories(fixturedefs, parentid)) faclist = list(fm._matchfactories(fixturedefs, parentid))
if faclist and name not in available: if faclist:
available.append(name) available.add(name)
msg = "fixture %r not found" % (self.argname,) if self.argname in available:
msg += "\n available fixtures: %s" % (", ".join(sorted(available)),) msg = " recursive dependency involving fixture '{}' detected".format(
self.argname
)
else:
msg = "fixture '{}' not found".format(self.argname)
msg += "\n available fixtures: {}".format(", ".join(sorted(available)))
msg += "\n use 'pytest --fixtures [testpath]' for help on them." msg += "\n use 'pytest --fixtures [testpath]' for help on them."
return FixtureLookupErrorRepr(fspath, lineno, tblines, msg, self.argname) return FixtureLookupErrorRepr(fspath, lineno, tblines, msg, self.argname)

View File

@ -0,0 +1,15 @@
import pytest
@pytest.fixture
def fix1(fix2):
return 1
@pytest.fixture
def fix2(fix1):
return 1
def test(fix1):
pass

View File

@ -60,6 +60,13 @@ class TestFillFixtures(object):
""" """
) )
def test_detect_recursive_dependency_error(self, testdir):
testdir.copy_example()
result = testdir.runpytest()
result.stdout.fnmatch_lines(
["*recursive dependency involving fixture 'fix1' detected*"]
)
def test_funcarg_basic(self, testdir): def test_funcarg_basic(self, testdir):
testdir.copy_example() testdir.copy_example()
item = testdir.getitem(Path("test_funcarg_basic.py")) item = testdir.getitem(Path("test_funcarg_basic.py"))