From 7d66e4eae1cc5989df07e140f2ff6949416c2c18 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Mon, 3 Oct 2016 20:47:44 -0300 Subject: [PATCH] Display full traceback from Import errors when collecting test modules Fix #1976 --- CHANGELOG.rst | 9 ++++++++- _pytest/python.py | 13 ++++++++----- testing/acceptance_test.py | 2 +- testing/python/collect.py | 22 +++++++++++++++++++++- testing/test_collection.py | 11 ----------- testing/test_terminal.py | 2 +- 6 files changed, 39 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6abd5006a..96a257781 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -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 ===== diff --git a/_pytest/python.py b/_pytest/python.py index 548d7cfa5..74bb4de43 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -424,12 +424,15 @@ class Module(pytest.File, PyCollector): % e.args ) 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( - "ImportError while importing test module '%s'.\n" - "Original error message:\n'%s'\n" - "Make sure your test modules/packages have valid Python names." - % (self.fspath, exc or exc_class) + "ImportError while importing test module '{fspath}'.\n" + "Hint: make sure your test modules/packages have valid Python names.\n" + "Original traceback:\n" + "{traceback}".format(fspath=self.fspath, traceback=formatted_tb) ) except _pytest.runner.Skipped as e: if e.allow_module_level: diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index b03f7fe4c..88e3fa449 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -120,7 +120,7 @@ class TestGeneralUsage: result.stdout.fnmatch_lines([ #XXX on jython this fails: "> import import_fails", "ImportError while importing test module*", - "'No module named *does_not_work*", + "*No module named *does_not_work*", ]) assert result.ret == 2 diff --git a/testing/python/collect.py b/testing/python/collect.py index 843f26a73..04ce53a54 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -68,9 +68,29 @@ class TestModule: result = testdir.runpytest("-rw") result.stdout.fnmatch_lines([ "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: def test_class_with_init_warning(self, testdir): diff --git a/testing/test_collection.py b/testing/test_collection.py index 8e44ba55d..71a64c3c9 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -172,17 +172,6 @@ class TestCollectPluginHookRelay: assert "world" in wascalled 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): p = testdir.makepyfile(""" diff --git a/testing/test_terminal.py b/testing/test_terminal.py index fc6f3b7b1..66214c80e 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -667,7 +667,7 @@ class TestGenericReporting: result = testdir.runpytest(*option.args) result.stdout.fnmatch_lines([ "ImportError while importing*", - "'No module named *xyz*", + "*No module named *xyz*", "*1 error*", ])