From 4e405dd9f96e69cdd53901db930a2d79bc4f7e58 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 22 Feb 2018 19:49:30 -0300 Subject: [PATCH] Show "short test summary info" after tracebacks and warnings --- _pytest/hookspec.py | 12 ++++++++++-- _pytest/skipping.py | 18 ++++++++++-------- _pytest/terminal.py | 13 +++++++++---- changelog/3255.feature.rst | 1 + testing/test_skipping.py | 15 +++++++++++++++ 5 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 changelog/3255.feature.rst diff --git a/_pytest/hookspec.py b/_pytest/hookspec.py index f1b1fe5a2..cffc4f8b0 100644 --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -489,8 +489,16 @@ def pytest_report_teststatus(report): Stops at first non-None result, see :ref:`firstresult` """ -def pytest_terminal_summary(terminalreporter, exitstatus): - """ add additional section in terminal summary reporting. """ +def pytest_terminal_summary(config, terminalreporter, exitstatus): + """Add a section to terminal summary reporting. + + :param _pytest.config.Config config: pytest config object + :param _pytest.terminal.TerminalReporter terminalreporter: the internal terminal reporter object + :param int exitstatus: the exit status that will be reported back to the OS + + .. versionadded:: 3.5 + The ``config`` parameter. + """ @hookspec(historic=True) diff --git a/_pytest/skipping.py b/_pytest/skipping.py index 1a4187c1b..48b837def 100644 --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -1,7 +1,6 @@ """ support for skip/xfail functions and markers. """ from __future__ import absolute_import, division, print_function - from _pytest.config import hookimpl from _pytest.mark import MarkInfo, MarkDecorator from _pytest.mark.evaluate import MarkEvaluator @@ -14,11 +13,11 @@ def pytest_addoption(parser): action="store_true", dest="runxfail", default=False, help="run tests even if they are marked xfail") - parser.addini("xfail_strict", "default for the strict parameter of xfail " - "markers when not given explicitly (default: " - "False)", - default=False, - type="bool") + parser.addini("xfail_strict", + "default for the strict parameter of xfail " + "markers when not given explicitly (default: False)", + default=False, + type="bool") def pytest_configure(config): @@ -130,7 +129,7 @@ def pytest_runtest_makereport(item, call): rep.outcome = "passed" rep.wasxfail = rep.longrepr elif item.config.option.runxfail: - pass # don't interefere + pass # don't interefere elif call.excinfo and call.excinfo.errisinstance(xfail.Exception): rep.wasxfail = "reason: " + call.excinfo.value.msg rep.outcome = "skipped" @@ -160,6 +159,7 @@ def pytest_runtest_makereport(item, call): filename, line = item.location[:2] rep.longrepr = filename, line, reason + # called by terminalreporter progress reporting @@ -170,6 +170,7 @@ def pytest_report_teststatus(report): elif report.passed: return "xpassed", "X", ("XPASS", {'yellow': True}) + # called by the terminalreporter instance/plugin @@ -233,7 +234,7 @@ def folded_skips(skipped): # TODO: revisit after marks scope would be fixed when = getattr(event, 'when', None) if when == 'setup' and 'skip' in keywords and 'pytestmark' not in keywords: - key = (key[0], None, key[2], ) + key = (key[0], None, key[2]) d.setdefault(key, []).append(event) values = [] for key, events in d.items(): @@ -269,6 +270,7 @@ def show_skipped(terminalreporter, lines): def shower(stat, format): def show_(terminalreporter, lines): return show_simple(terminalreporter, lines, stat, format) + return show_ diff --git a/_pytest/terminal.py b/_pytest/terminal.py index 55a632b22..90c5d87d9 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -480,16 +480,21 @@ class TerminalReporter(object): EXIT_NOTESTSCOLLECTED) if exitstatus in summary_exit_codes: self.config.hook.pytest_terminal_summary(terminalreporter=self, + config=self.config, exitstatus=exitstatus) - self.summary_errors() - self.summary_failures() - self.summary_warnings() - self.summary_passes() if exitstatus == EXIT_INTERRUPTED: self._report_keyboardinterrupt() del self._keyboardinterrupt_memo self.summary_stats() + @pytest.hookimpl(hookwrapper=True) + def pytest_terminal_summary(self): + self.summary_errors() + self.summary_failures() + yield + self.summary_warnings() + self.summary_passes() + def pytest_keyboard_interrupt(self, excinfo): self._keyboardinterrupt_memo = excinfo.getrepr(funcargs=True) diff --git a/changelog/3255.feature.rst b/changelog/3255.feature.rst new file mode 100644 index 000000000..d4994740d --- /dev/null +++ b/changelog/3255.feature.rst @@ -0,0 +1 @@ +The *short test summary info* section now is displayed after tracebacks and warnings in the terminal. diff --git a/testing/test_skipping.py b/testing/test_skipping.py index db4e6d3f7..161a6e69e 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -1065,3 +1065,18 @@ def test_mark_xfail_item(testdir): assert not failed xfailed = [r for r in skipped if hasattr(r, 'wasxfail')] assert xfailed + + +def test_summary_list_after_errors(testdir): + """Ensure the list of errors/fails/xfails/skips appear after tracebacks in terminal reporting.""" + testdir.makepyfile(""" + import pytest + def test_fail(): + assert 0 + """) + result = testdir.runpytest('-ra') + result.stdout.fnmatch_lines([ + '=* FAILURES *=', + '*= short test summary info =*', + 'FAIL test_summary_list_after_errors.py::test_fail', + ])