summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/_pytest/skipping.py125
-rw-r--r--src/_pytest/terminal.py122
-rw-r--r--testing/test_skipping.py35
-rw-r--r--testing/test_terminal.py35
4 files changed, 157 insertions, 160 deletions
diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py
index 22acafbdd..3f488fad5 100644
--- a/src/_pytest/skipping.py
+++ b/src/_pytest/skipping.py
@@ -183,128 +183,3 @@ def pytest_report_teststatus(report):
return "xfailed", "x", "XFAIL"
elif report.passed:
return "xpassed", "X", "XPASS"
-
-
-# called by the terminalreporter instance/plugin
-
-
-def pytest_terminal_summary(terminalreporter):
- tr = terminalreporter
- if not tr.reportchars:
- return
-
- lines = []
- for char in tr.reportchars:
- action = REPORTCHAR_ACTIONS.get(char, lambda tr, lines: None)
- action(terminalreporter, lines)
-
- if lines:
- tr._tw.sep("=", "short test summary info")
- for line in lines:
- tr._tw.line(line)
-
-
-def show_simple(terminalreporter, lines, stat):
- failed = terminalreporter.stats.get(stat)
- if failed:
- config = terminalreporter.config
- for rep in failed:
- verbose_word = _get_report_str(config, rep)
- pos = _get_pos(config, rep)
- lines.append("%s %s" % (verbose_word, pos))
-
-
-def show_xfailed(terminalreporter, lines):
- xfailed = terminalreporter.stats.get("xfailed")
- if xfailed:
- config = terminalreporter.config
- for rep in xfailed:
- verbose_word = _get_report_str(config, rep)
- pos = _get_pos(config, rep)
- lines.append("%s %s" % (verbose_word, pos))
- reason = rep.wasxfail
- if reason:
- lines.append(" " + str(reason))
-
-
-def show_xpassed(terminalreporter, lines):
- xpassed = terminalreporter.stats.get("xpassed")
- if xpassed:
- config = terminalreporter.config
- for rep in xpassed:
- verbose_word = _get_report_str(config, rep)
- pos = _get_pos(config, rep)
- reason = rep.wasxfail
- lines.append("%s %s %s" % (verbose_word, pos, reason))
-
-
-def folded_skips(skipped):
- d = {}
- for event in skipped:
- key = event.longrepr
- assert len(key) == 3, (event, key)
- keywords = getattr(event, "keywords", {})
- # folding reports with global pytestmark variable
- # this is workaround, because for now we cannot identify the scope of a skip marker
- # TODO: revisit after marks scope would be fixed
- if (
- event.when == "setup"
- and "skip" in keywords
- and "pytestmark" not in keywords
- ):
- key = (key[0], None, key[2])
- d.setdefault(key, []).append(event)
- values = []
- for key, events in d.items():
- values.append((len(events),) + key)
- return values
-
-
-def show_skipped(terminalreporter, lines):
- tr = terminalreporter
- skipped = tr.stats.get("skipped", [])
- if skipped:
- fskips = folded_skips(skipped)
- if fskips:
- verbose_word = _get_report_str(terminalreporter.config, report=skipped[0])
- for num, fspath, lineno, reason in fskips:
- if reason.startswith("Skipped: "):
- reason = reason[9:]
- if lineno is not None:
- lines.append(
- "%s [%d] %s:%d: %s"
- % (verbose_word, num, fspath, lineno + 1, reason)
- )
- else:
- lines.append("%s [%d] %s: %s" % (verbose_word, num, fspath, reason))
-
-
-def shower(stat):
- def show_(terminalreporter, lines):
- return show_simple(terminalreporter, lines, stat)
-
- return show_
-
-
-def _get_report_str(config, report):
- _category, _short, verbose = config.hook.pytest_report_teststatus(
- report=report, config=config
- )
- return verbose
-
-
-def _get_pos(config, rep):
- nodeid = config.cwd_relative_nodeid(rep.nodeid)
- return nodeid
-
-
-REPORTCHAR_ACTIONS = {
- "x": show_xfailed,
- "X": show_xpassed,
- "f": shower("failed"),
- "F": shower("failed"),
- "s": show_skipped,
- "S": show_skipped,
- "p": shower("passed"),
- "E": shower("error"),
-}
diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py
index 31c0da46d..8d6abb17a 100644
--- a/src/_pytest/terminal.py
+++ b/src/_pytest/terminal.py
@@ -874,6 +874,128 @@ class TerminalReporter(object):
self.write_line(msg, **markup)
+def pytest_terminal_summary(terminalreporter):
+ tr = terminalreporter
+ if not tr.reportchars:
+ return
+
+ lines = []
+ for char in tr.reportchars:
+ action = REPORTCHAR_ACTIONS.get(char, lambda tr, lines: None)
+ action(terminalreporter, lines)
+
+ if lines:
+ tr._tw.sep("=", "short test summary info")
+ for line in lines:
+ tr._tw.line(line)
+
+
+def show_simple(terminalreporter, lines, stat):
+ failed = terminalreporter.stats.get(stat)
+ if failed:
+ config = terminalreporter.config
+ for rep in failed:
+ verbose_word = _get_report_str(config, rep)
+ pos = _get_pos(config, rep)
+ lines.append("%s %s" % (verbose_word, pos))
+
+
+def show_xfailed(terminalreporter, lines):
+ xfailed = terminalreporter.stats.get("xfailed")
+ if xfailed:
+ config = terminalreporter.config
+ for rep in xfailed:
+ verbose_word = _get_report_str(config, rep)
+ pos = _get_pos(config, rep)
+ lines.append("%s %s" % (verbose_word, pos))
+ reason = rep.wasxfail
+ if reason:
+ lines.append(" " + str(reason))
+
+
+def show_xpassed(terminalreporter, lines):
+ xpassed = terminalreporter.stats.get("xpassed")
+ if xpassed:
+ config = terminalreporter.config
+ for rep in xpassed:
+ verbose_word = _get_report_str(config, rep)
+ pos = _get_pos(config, rep)
+ reason = rep.wasxfail
+ lines.append("%s %s %s" % (verbose_word, pos, reason))
+
+
+def folded_skips(skipped):
+ d = {}
+ for event in skipped:
+ key = event.longrepr
+ assert len(key) == 3, (event, key)
+ keywords = getattr(event, "keywords", {})
+ # folding reports with global pytestmark variable
+ # this is workaround, because for now we cannot identify the scope of a skip marker
+ # TODO: revisit after marks scope would be fixed
+ if (
+ event.when == "setup"
+ and "skip" in keywords
+ and "pytestmark" not in keywords
+ ):
+ key = (key[0], None, key[2])
+ d.setdefault(key, []).append(event)
+ values = []
+ for key, events in d.items():
+ values.append((len(events),) + key)
+ return values
+
+
+def show_skipped(terminalreporter, lines):
+ tr = terminalreporter
+ skipped = tr.stats.get("skipped", [])
+ if skipped:
+ fskips = folded_skips(skipped)
+ if fskips:
+ verbose_word = _get_report_str(terminalreporter.config, report=skipped[0])
+ for num, fspath, lineno, reason in fskips:
+ if reason.startswith("Skipped: "):
+ reason = reason[9:]
+ if lineno is not None:
+ lines.append(
+ "%s [%d] %s:%d: %s"
+ % (verbose_word, num, fspath, lineno + 1, reason)
+ )
+ else:
+ lines.append("%s [%d] %s: %s" % (verbose_word, num, fspath, reason))
+
+
+def shower(stat):
+ def show_(terminalreporter, lines):
+ return show_simple(terminalreporter, lines, stat)
+
+ return show_
+
+
+def _get_report_str(config, report):
+ _category, _short, verbose = config.hook.pytest_report_teststatus(
+ report=report, config=config
+ )
+ return verbose
+
+
+def _get_pos(config, rep):
+ nodeid = config.cwd_relative_nodeid(rep.nodeid)
+ return nodeid
+
+
+REPORTCHAR_ACTIONS = {
+ "x": show_xfailed,
+ "X": show_xpassed,
+ "f": shower("failed"),
+ "F": shower("failed"),
+ "s": show_skipped,
+ "S": show_skipped,
+ "p": shower("passed"),
+ "E": shower("error"),
+}
+
+
def build_summary_stats_line(stats):
known_types = (
"failed passed skipped deselected xfailed xpassed warnings error".split()
diff --git a/testing/test_skipping.py b/testing/test_skipping.py
index e5206a44e..cef0fe6ee 100644
--- a/testing/test_skipping.py
+++ b/testing/test_skipping.py
@@ -6,7 +6,6 @@ import sys
import pytest
from _pytest.runner import runtestprotocol
-from _pytest.skipping import folded_skips
from _pytest.skipping import MarkEvaluator
from _pytest.skipping import pytest_runtest_setup
@@ -749,40 +748,6 @@ def test_skipif_class(testdir):
result.stdout.fnmatch_lines(["*2 skipped*"])
-def test_skip_reasons_folding():
- path = "xyz"
- lineno = 3
- message = "justso"
- longrepr = (path, lineno, message)
-
- class X(object):
- pass
-
- ev1 = X()
- ev1.when = "execute"
- ev1.skipped = True
- ev1.longrepr = longrepr
-
- ev2 = X()
- ev2.when = "execute"
- ev2.longrepr = longrepr
- ev2.skipped = True
-
- # ev3 might be a collection report
- ev3 = X()
- ev3.when = "collect"
- ev3.longrepr = longrepr
- ev3.skipped = True
-
- values = folded_skips([ev1, ev2, ev3])
- assert len(values) == 1
- num, fspath, lineno, reason = values[0]
- assert num == 3
- assert fspath == path
- assert lineno == lineno
- assert reason == message
-
-
def test_skipped_reasons_functional(testdir):
testdir.makepyfile(
test_one="""
diff --git a/testing/test_terminal.py b/testing/test_terminal.py
index d0fdce23e..888104bf3 100644
--- a/testing/test_terminal.py
+++ b/testing/test_terminal.py
@@ -18,6 +18,7 @@ from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.reports import BaseReport
from _pytest.terminal import _plugin_nameversions
from _pytest.terminal import build_summary_stats_line
+from _pytest.terminal import folded_skips
from _pytest.terminal import getreportopt
from _pytest.terminal import TerminalReporter
@@ -1524,3 +1525,37 @@ class TestProgressWithTeardown(object):
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
output = testdir.runpytest("-n2")
output.stdout.re_match_lines([r"[\.E]{40} \s+ \[100%\]"])
+
+
+def test_skip_reasons_folding():
+ path = "xyz"
+ lineno = 3
+ message = "justso"
+ longrepr = (path, lineno, message)
+
+ class X(object):
+ pass
+
+ ev1 = X()
+ ev1.when = "execute"
+ ev1.skipped = True
+ ev1.longrepr = longrepr
+
+ ev2 = X()
+ ev2.when = "execute"
+ ev2.longrepr = longrepr
+ ev2.skipped = True
+
+ # ev3 might be a collection report
+ ev3 = X()
+ ev3.when = "collect"
+ ev3.longrepr = longrepr
+ ev3.skipped = True
+
+ values = folded_skips([ev1, ev2, ev3])
+ assert len(values) == 1
+ num, fspath, lineno, reason = values[0]
+ assert num == 3
+ assert fspath == path
+ assert lineno == lineno
+ assert reason == message