fix 'DoctestItem' object has no attribute '_fixtureinfo'

* doxtests don't seem to have this attribute, so nothing will be written in that case.
* tried to be a good boy scout and tidied up surrounding code a bit (comments, shadowed/unused names, removed random new lines, naming things)
This commit is contained in:
Oliver Bestwalter 2017-09-19 12:41:12 +02:00
parent bf77daa2ee
commit 2802135741
No known key found for this signature in database
GPG Key ID: 8AF6D5F5A0469150
3 changed files with 40 additions and 20 deletions

View File

@ -979,50 +979,48 @@ def _show_fixtures_per_test(config, session):
tw = _pytest.config.create_terminal_writer(config) tw = _pytest.config.create_terminal_writer(config)
verbose = config.getvalue("verbose") verbose = config.getvalue("verbose")
def get_best_rel(func): def get_best_relpath(func):
loc = getlocation(func, curdir) loc = getlocation(func, curdir)
return curdir.bestrelpath(loc) return curdir.bestrelpath(loc)
def write_fixture(fixture_def): def write_fixture(fixture_def):
argname = fixture_def.argname argname = fixture_def.argname
if verbose <= 0 and argname.startswith("_"): if verbose <= 0 and argname.startswith("_"):
return return
if verbose > 0: if verbose > 0:
bestrel = get_best_rel(fixture_def.func) bestrel = get_best_relpath(fixture_def.func)
funcargspec = "{0} -- {1}".format(argname, bestrel) funcargspec = "{0} -- {1}".format(argname, bestrel)
else: else:
funcargspec = argname funcargspec = argname
tw.line(funcargspec, green=True) tw.line(funcargspec, green=True)
fixture_doc = fixture_def.func.__doc__ fixture_doc = fixture_def.func.__doc__
if fixture_doc: if fixture_doc:
write_docstring(tw, fixture_doc) write_docstring(tw, fixture_doc)
else: else:
tw.line(' no docstring available', red=True) tw.line(' no docstring available', red=True)
def write_item(item): def write_item(item):
name2fixturedefs = item._fixtureinfo.name2fixturedefs try:
info = item._fixtureinfo
if not name2fixturedefs: except AttributeError:
# The given test item does not use any fixtures # doctests items have no _fixtureinfo attribute
return
if not info.name2fixturedefs:
# this test item does not use any fixtures
return return
bestrel = get_best_rel(item.function)
tw.line() tw.line()
tw.sep('-', 'fixtures used by {0}'.format(item.name)) tw.sep('-', 'fixtures used by {0}'.format(item.name))
tw.sep('-', '({0})'.format(bestrel)) tw.sep('-', '({0})'.format(get_best_relpath(item.function)))
for argname, fixture_defs in sorted(name2fixturedefs.items()): # dict key not used in loop but needed for sorting
assert fixture_defs is not None for _, fixturedefs in sorted(info.name2fixturedefs.items()):
if not fixture_defs: assert fixturedefs is not None
if not fixturedefs:
continue continue
# The last fixture def item in the list is expected # last item is expected to be the one used by the test item
# to be the one used by the test item write_fixture(fixturedefs[-1])
write_fixture(fixture_defs[-1])
for item in session.items: for session_item in session.items:
write_item(item) write_item(session_item)
def showfixtures(config): def showfixtures(config):

1
changelog/2788.bugfix Normal file
View File

@ -0,0 +1 @@
When running ``pytest --fixtures-per-test``: don't crash if an item has no _fixtureinfo attribute (e.g. doctests)

View File

@ -135,3 +135,24 @@ def test_verbose_include_private_fixtures_and_loc(testdir):
'arg3 -- test_verbose_include_private_fixtures_and_loc.py:3', 'arg3 -- test_verbose_include_private_fixtures_and_loc.py:3',
' arg3 from testmodule', ' arg3 from testmodule',
]) ])
def test_doctest_items(testdir):
testdir.makepyfile('''
def foo():
"""
>>> 1 + 1
2
"""
''')
testdir.maketxtfile('''
>>> 1 + 1
2
''')
result = testdir.runpytest("--fixtures-per-test", "--doctest-modules",
"--doctest-glob=*.txt", "-v")
assert result.ret == 0
result.stdout.fnmatch_lines([
'*collected 2 items*',
])