Display full traceback from Import errors when collecting test modules

Fix #1976
This commit is contained in:
Bruno Oliveira 2016-10-03 20:47:44 -03:00
parent fc02003220
commit 7d66e4eae1
6 changed files with 39 additions and 20 deletions

View File

@ -3,13 +3,20 @@
* *
* * Import errors when collecting test modules now display the full traceback (`#1976`_).
Thanks `@cwitty`_ for the report and `@nicoddemus`_ for the PR.
* *
* *
.. _@cwitty: https://github.com/cwitty
.. _#1976: https://github.com/pytest-dev/pytest/issues/1976
3.0.3 3.0.3
===== =====

View File

@ -424,12 +424,15 @@ class Module(pytest.File, PyCollector):
% e.args % e.args
) )
except ImportError: except ImportError:
exc_class, exc, _ = sys.exc_info() import traceback
stream = py.io.TextIO()
traceback.print_exc(file=stream)
formatted_tb = stream.getvalue()
raise self.CollectError( raise self.CollectError(
"ImportError while importing test module '%s'.\n" "ImportError while importing test module '{fspath}'.\n"
"Original error message:\n'%s'\n" "Hint: make sure your test modules/packages have valid Python names.\n"
"Make sure your test modules/packages have valid Python names." "Original traceback:\n"
% (self.fspath, exc or exc_class) "{traceback}".format(fspath=self.fspath, traceback=formatted_tb)
) )
except _pytest.runner.Skipped as e: except _pytest.runner.Skipped as e:
if e.allow_module_level: if e.allow_module_level:

View File

@ -120,7 +120,7 @@ class TestGeneralUsage:
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
#XXX on jython this fails: "> import import_fails", #XXX on jython this fails: "> import import_fails",
"ImportError while importing test module*", "ImportError while importing test module*",
"'No module named *does_not_work*", "*No module named *does_not_work*",
]) ])
assert result.ret == 2 assert result.ret == 2

View File

@ -68,9 +68,29 @@ class TestModule:
result = testdir.runpytest("-rw") result = testdir.runpytest("-rw")
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
"ImportError while importing test module*test_one.part1*", "ImportError while importing test module*test_one.part1*",
"Make sure your test modules/packages have valid Python names.", "Hint: make sure your test modules/packages have valid Python names.",
]) ])
def test_show_full_traceback_import_error(self, testdir):
"""Import errors when collecting modules should display the full traceback (#1976)."""
testdir.makepyfile(
foo_traceback_import_error="""
from bar_traceback_import_error import NOT_AVAILABLE
""",
bar_traceback_import_error="",
)
testdir.makepyfile("""
import foo_traceback_import_error
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines([
"ImportError while importing test module*",
"Original traceback:",
"*from bar_traceback_import_error import NOT_AVAILABLE",
"*cannot import name *NOT_AVAILABLE*",
])
assert result.ret == 2
class TestClass: class TestClass:
def test_class_with_init_warning(self, testdir): def test_class_with_init_warning(self, testdir):

View File

@ -172,17 +172,6 @@ class TestCollectPluginHookRelay:
assert "world" in wascalled assert "world" in wascalled
class TestPrunetraceback: class TestPrunetraceback:
def test_collection_error(self, testdir):
p = testdir.makepyfile("""
import not_exists
""")
result = testdir.runpytest(p)
assert "__import__" not in result.stdout.str(), "too long traceback"
result.stdout.fnmatch_lines([
"*ERROR collecting*",
"ImportError while importing test module*",
"'No module named *not_exists*",
])
def test_custom_repr_failure(self, testdir): def test_custom_repr_failure(self, testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""

View File

@ -667,7 +667,7 @@ class TestGenericReporting:
result = testdir.runpytest(*option.args) result = testdir.runpytest(*option.args)
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
"ImportError while importing*", "ImportError while importing*",
"'No module named *xyz*", "*No module named *xyz*",
"*1 error*", "*1 error*",
]) ])