From 37ecca3ba9b1715735ec745b975f75327c3261b7 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 4 Apr 2019 22:13:28 +0200 Subject: [PATCH] factor out _get_line_with_reprcrash_message --- changelog/5013.feature.rst | 1 + src/_pytest/skipping.py | 58 +++++++++++++++++++++++++------------- testing/test_skipping.py | 44 +++++++++++++++++++++++++++++ testing/test_terminal.py | 2 +- 4 files changed, 84 insertions(+), 21 deletions(-) create mode 100644 changelog/5013.feature.rst diff --git a/changelog/5013.feature.rst b/changelog/5013.feature.rst new file mode 100644 index 000000000..08f82efeb --- /dev/null +++ b/changelog/5013.feature.rst @@ -0,0 +1 @@ +Messages from crash reports are displayed within test summaries now, truncated to the terminal width. diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py index 9abed5b1f..e72eecccf 100644 --- a/src/_pytest/skipping.py +++ b/src/_pytest/skipping.py @@ -204,31 +204,49 @@ def pytest_terminal_summary(terminalreporter): tr._tw.line(line) +def _get_line_with_reprcrash_message(config, rep, termwidth): + """Get summary line for a report, trying to add reprcrash message.""" + verbose_word = _get_report_str(config, rep) + pos = _get_pos(config, rep) + + line = "%s %s" % (verbose_word, pos) + + len_line = len(line) + ellipsis = "..." + len_ellipsis = len(ellipsis) + + if len_line > termwidth - len_ellipsis: + # No space for an additional message. + return line + + try: + msg = rep.longrepr.reprcrash.message + except AttributeError: + pass + else: + # Only use the first line. + i = msg.find("\n") + if i != -1: + msg = msg[:i] + len_msg = len(msg) + + sep = ": " + len_sep = len(sep) + max_len = termwidth - len_line - len_sep + if max_len >= len_ellipsis: + if len_msg > max_len: + msg = msg[: (max_len - len_ellipsis)] + ellipsis + line += sep + msg + return line + + def show_simple(terminalreporter, lines, stat): failed = terminalreporter.stats.get(stat) if failed: config = terminalreporter.config + termwidth = terminalreporter.writer.fullwidth for rep in failed: - verbose_word = _get_report_str(config, rep) - pos = _get_pos(config, rep) - - line = "%s %s" % (verbose_word, pos) - try: - msg = rep.longrepr.reprcrash.message - except AttributeError: - pass - else: - # Only use the first line. - # Might be worth having a short_message property, which - # could default to this behavior. - i = msg.find("\n") - if i != -1: - msg = msg[:i] - max_len = terminalreporter.writer.fullwidth - len(line) - 2 - if len(msg) > max_len: - msg = msg[: (max_len - 1)] + "…" - line += ": %s" % msg - + line = _get_line_with_reprcrash_message(config, rep, termwidth) lines.append(line) diff --git a/testing/test_skipping.py b/testing/test_skipping.py index fb0cf60e0..93dd2a97d 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -1211,3 +1211,47 @@ def test_summary_list_after_errors(testdir): "FAILED test_summary_list_after_errors.py::test_fail: assert 0", ] ) + + +def test_line_with_reprcrash(monkeypatch): + import _pytest.skipping + from _pytest.skipping import _get_line_with_reprcrash_message + + def mock_get_report_str(*args): + return "FAILED" + + def mock_get_pos(*args): + return "some::nodeid" + + monkeypatch.setattr(_pytest.skipping, "_get_report_str", mock_get_report_str) + monkeypatch.setattr(_pytest.skipping, "_get_pos", mock_get_pos) + + class config: + pass + + class rep: + pass + + f = _get_line_with_reprcrash_message + assert f(config, rep, 80) == "FAILED some::nodeid" + + class rep: + class longrepr: + class reprcrash: + message = "msg" + + assert f(config, rep, 80) == "FAILED some::nodeid: msg" + assert f(config, rep, 3) == "FAILED some::nodeid" + + assert f(config, rep, 23) == "FAILED some::nodeid" + assert f(config, rep, 24) == "FAILED some::nodeid: msg" + + rep.longrepr.reprcrash.message = "some longer message" + assert f(config, rep, 23) == "FAILED some::nodeid" + assert f(config, rep, 24) == "FAILED some::nodeid: ..." + assert f(config, rep, 25) == "FAILED some::nodeid: s..." + + rep.longrepr.reprcrash.message = "some\nmessage" + assert f(config, rep, 24) == "FAILED some::nodeid: ..." + assert f(config, rep, 25) == "FAILED some::nodeid: some" + assert f(config, rep, 80) == "FAILED some::nodeid: some" diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 9b221366f..c465fc903 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -735,7 +735,7 @@ def test_fail_extra_reporting(testdir, monkeypatch): result.stdout.fnmatch_lines( [ "*test summary*", - "FAILED test_fail_extra_reporting.py::test_this: AssertionError: this_failedthis…", + "FAILED test_fail_extra_reporting.py::test_this: AssertionError: this_failedth...", ] )