pytest_terminal_summary uses result from pytest_report_teststatus hook, rather than hardcoded strings
Less hacky way to make XPASS yellow markup. Make sure collect reports still have a "when" attribute. xfail changed to XFAIL in the test report, for consistency with other outcomes which are all CAPS
This commit is contained in:
parent
ba452dbcf0
commit
0f546c4670
|
@ -0,0 +1 @@
|
||||||
|
``pytest_terminal_summary`` uses result from ``pytest_report_teststatus`` hook, rather than hardcoded strings.
|
|
@ -213,7 +213,7 @@ class _NodeReporter(object):
|
||||||
self._add_simple(Junit.skipped, "collection skipped", report.longrepr)
|
self._add_simple(Junit.skipped, "collection skipped", report.longrepr)
|
||||||
|
|
||||||
def append_error(self, report):
|
def append_error(self, report):
|
||||||
if getattr(report, "when", None) == "teardown":
|
if report.when == "teardown":
|
||||||
msg = "test teardown failure"
|
msg = "test teardown failure"
|
||||||
else:
|
else:
|
||||||
msg = "test setup failure"
|
msg = "test setup failure"
|
||||||
|
|
|
@ -19,6 +19,8 @@ def getslaveinfoline(node):
|
||||||
|
|
||||||
|
|
||||||
class BaseReport(object):
|
class BaseReport(object):
|
||||||
|
when = None
|
||||||
|
|
||||||
def __init__(self, **kw):
|
def __init__(self, **kw):
|
||||||
self.__dict__.update(kw)
|
self.__dict__.update(kw)
|
||||||
|
|
||||||
|
@ -169,6 +171,8 @@ class TeardownErrorReport(BaseReport):
|
||||||
|
|
||||||
|
|
||||||
class CollectReport(BaseReport):
|
class CollectReport(BaseReport):
|
||||||
|
when = "collect"
|
||||||
|
|
||||||
def __init__(self, nodeid, outcome, longrepr, result, sections=(), **extra):
|
def __init__(self, nodeid, outcome, longrepr, result, sections=(), **extra):
|
||||||
self.nodeid = nodeid
|
self.nodeid = nodeid
|
||||||
self.outcome = outcome
|
self.outcome = outcome
|
||||||
|
|
|
@ -180,9 +180,9 @@ def pytest_runtest_makereport(item, call):
|
||||||
def pytest_report_teststatus(report):
|
def pytest_report_teststatus(report):
|
||||||
if hasattr(report, "wasxfail"):
|
if hasattr(report, "wasxfail"):
|
||||||
if report.skipped:
|
if report.skipped:
|
||||||
return "xfailed", "x", "xfail"
|
return "xfailed", "x", "XFAIL"
|
||||||
elif report.passed:
|
elif report.passed:
|
||||||
return "xpassed", "X", ("XPASS", {"yellow": True})
|
return "xpassed", "X", "XPASS"
|
||||||
|
|
||||||
|
|
||||||
# called by the terminalreporter instance/plugin
|
# called by the terminalreporter instance/plugin
|
||||||
|
@ -191,11 +191,6 @@ def pytest_report_teststatus(report):
|
||||||
def pytest_terminal_summary(terminalreporter):
|
def pytest_terminal_summary(terminalreporter):
|
||||||
tr = terminalreporter
|
tr = terminalreporter
|
||||||
if not tr.reportchars:
|
if not tr.reportchars:
|
||||||
# for name in "xfailed skipped failed xpassed":
|
|
||||||
# if not tr.stats.get(name, 0):
|
|
||||||
# tr.write_line("HINT: use '-r' option to see extra "
|
|
||||||
# "summary info about tests")
|
|
||||||
# break
|
|
||||||
return
|
return
|
||||||
|
|
||||||
lines = []
|
lines = []
|
||||||
|
@ -209,21 +204,23 @@ def pytest_terminal_summary(terminalreporter):
|
||||||
tr._tw.line(line)
|
tr._tw.line(line)
|
||||||
|
|
||||||
|
|
||||||
def show_simple(terminalreporter, lines, stat, format):
|
def show_simple(terminalreporter, lines, stat):
|
||||||
failed = terminalreporter.stats.get(stat)
|
failed = terminalreporter.stats.get(stat)
|
||||||
if failed:
|
if failed:
|
||||||
for rep in failed:
|
for rep in failed:
|
||||||
|
verbose_word = _get_report_str(terminalreporter, rep)
|
||||||
pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
|
pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
|
||||||
lines.append(format % (pos,))
|
lines.append("%s %s" % (verbose_word, pos))
|
||||||
|
|
||||||
|
|
||||||
def show_xfailed(terminalreporter, lines):
|
def show_xfailed(terminalreporter, lines):
|
||||||
xfailed = terminalreporter.stats.get("xfailed")
|
xfailed = terminalreporter.stats.get("xfailed")
|
||||||
if xfailed:
|
if xfailed:
|
||||||
for rep in xfailed:
|
for rep in xfailed:
|
||||||
|
verbose_word = _get_report_str(terminalreporter, rep)
|
||||||
pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
|
pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
|
||||||
reason = rep.wasxfail
|
reason = rep.wasxfail
|
||||||
lines.append("XFAIL %s" % (pos,))
|
lines.append("%s %s" % (verbose_word, pos))
|
||||||
if reason:
|
if reason:
|
||||||
lines.append(" " + str(reason))
|
lines.append(" " + str(reason))
|
||||||
|
|
||||||
|
@ -232,9 +229,10 @@ def show_xpassed(terminalreporter, lines):
|
||||||
xpassed = terminalreporter.stats.get("xpassed")
|
xpassed = terminalreporter.stats.get("xpassed")
|
||||||
if xpassed:
|
if xpassed:
|
||||||
for rep in xpassed:
|
for rep in xpassed:
|
||||||
|
verbose_word = _get_report_str(terminalreporter, rep)
|
||||||
pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
|
pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
|
||||||
reason = rep.wasxfail
|
reason = rep.wasxfail
|
||||||
lines.append("XPASS %s %s" % (pos, reason))
|
lines.append("%s %s %s" % (verbose_word, pos, reason))
|
||||||
|
|
||||||
|
|
||||||
def folded_skips(skipped):
|
def folded_skips(skipped):
|
||||||
|
@ -260,39 +258,42 @@ def show_skipped(terminalreporter, lines):
|
||||||
tr = terminalreporter
|
tr = terminalreporter
|
||||||
skipped = tr.stats.get("skipped", [])
|
skipped = tr.stats.get("skipped", [])
|
||||||
if skipped:
|
if skipped:
|
||||||
# if not tr.hasopt('skipped'):
|
verbose_word = _get_report_str(terminalreporter, report=skipped[0])
|
||||||
# tr.write_line(
|
|
||||||
# "%d skipped tests, specify -rs for more info" %
|
|
||||||
# len(skipped))
|
|
||||||
# return
|
|
||||||
fskips = folded_skips(skipped)
|
fskips = folded_skips(skipped)
|
||||||
if fskips:
|
if fskips:
|
||||||
# tr.write_sep("_", "skipped test summary")
|
|
||||||
for num, fspath, lineno, reason in fskips:
|
for num, fspath, lineno, reason in fskips:
|
||||||
if reason.startswith("Skipped: "):
|
if reason.startswith("Skipped: "):
|
||||||
reason = reason[9:]
|
reason = reason[9:]
|
||||||
if lineno is not None:
|
if lineno is not None:
|
||||||
lines.append(
|
lines.append(
|
||||||
"SKIP [%d] %s:%d: %s" % (num, fspath, lineno + 1, reason)
|
"%s [%d] %s:%d: %s"
|
||||||
|
% (verbose_word, num, fspath, lineno + 1, reason)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
lines.append("SKIP [%d] %s: %s" % (num, fspath, reason))
|
lines.append("%s [%d] %s: %s" % (verbose_word, num, fspath, reason))
|
||||||
|
|
||||||
|
|
||||||
def shower(stat, format):
|
def shower(stat):
|
||||||
def show_(terminalreporter, lines):
|
def show_(terminalreporter, lines):
|
||||||
return show_simple(terminalreporter, lines, stat, format)
|
return show_simple(terminalreporter, lines, stat)
|
||||||
|
|
||||||
return show_
|
return show_
|
||||||
|
|
||||||
|
|
||||||
|
def _get_report_str(terminalreporter, report):
|
||||||
|
_category, _short, verbose = terminalreporter.config.hook.pytest_report_teststatus(
|
||||||
|
report=report
|
||||||
|
)
|
||||||
|
return verbose
|
||||||
|
|
||||||
|
|
||||||
REPORTCHAR_ACTIONS = {
|
REPORTCHAR_ACTIONS = {
|
||||||
"x": show_xfailed,
|
"x": show_xfailed,
|
||||||
"X": show_xpassed,
|
"X": show_xpassed,
|
||||||
"f": shower("failed", "FAIL %s"),
|
"f": shower("failed"),
|
||||||
"F": shower("failed", "FAIL %s"),
|
"F": shower("failed"),
|
||||||
"s": show_skipped,
|
"s": show_skipped,
|
||||||
"S": show_skipped,
|
"S": show_skipped,
|
||||||
"p": shower("passed", "PASSED %s"),
|
"p": shower("passed"),
|
||||||
"E": shower("error", "ERROR %s"),
|
"E": shower("error"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,8 +376,11 @@ class TerminalReporter(object):
|
||||||
return
|
return
|
||||||
running_xdist = hasattr(rep, "node")
|
running_xdist = hasattr(rep, "node")
|
||||||
if markup is None:
|
if markup is None:
|
||||||
if rep.passed:
|
was_xfail = hasattr(report, "wasxfail")
|
||||||
|
if rep.passed and not was_xfail:
|
||||||
markup = {"green": True}
|
markup = {"green": True}
|
||||||
|
elif rep.passed and was_xfail:
|
||||||
|
markup = {"yellow": True}
|
||||||
elif rep.failed:
|
elif rep.failed:
|
||||||
markup = {"red": True}
|
markup = {"red": True}
|
||||||
elif rep.skipped:
|
elif rep.skipped:
|
||||||
|
@ -806,8 +809,7 @@ class TerminalReporter(object):
|
||||||
self.write_sep("=", "ERRORS")
|
self.write_sep("=", "ERRORS")
|
||||||
for rep in self.stats["error"]:
|
for rep in self.stats["error"]:
|
||||||
msg = self._getfailureheadline(rep)
|
msg = self._getfailureheadline(rep)
|
||||||
if not hasattr(rep, "when"):
|
if rep.when == "collect":
|
||||||
# collect
|
|
||||||
msg = "ERROR collecting " + msg
|
msg = "ERROR collecting " + msg
|
||||||
elif rep.when == "setup":
|
elif rep.when == "setup":
|
||||||
msg = "ERROR at setup of " + msg
|
msg = "ERROR at setup of " + msg
|
||||||
|
|
|
@ -804,8 +804,8 @@ class TestInvocationVariants(object):
|
||||||
result = testdir.runpytest("-rf")
|
result = testdir.runpytest("-rf")
|
||||||
lines = result.stdout.str().splitlines()
|
lines = result.stdout.str().splitlines()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if line.startswith("FAIL "):
|
if line.startswith(("FAIL ", "FAILED ")):
|
||||||
testid = line[5:].strip()
|
_fail, _sep, testid = line.partition(" ")
|
||||||
break
|
break
|
||||||
result = testdir.runpytest(testid, "-rf")
|
result = testdir.runpytest(testid, "-rf")
|
||||||
result.stdout.fnmatch_lines([line, "*1 failed*"])
|
result.stdout.fnmatch_lines([line, "*1 failed*"])
|
||||||
|
|
|
@ -1202,6 +1202,6 @@ def test_summary_list_after_errors(testdir):
|
||||||
[
|
[
|
||||||
"=* FAILURES *=",
|
"=* FAILURES *=",
|
||||||
"*= short test summary info =*",
|
"*= short test summary info =*",
|
||||||
"FAIL test_summary_list_after_errors.py::test_fail",
|
"FAILED test_summary_list_after_errors.py::test_fail",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
@ -625,7 +625,7 @@ class TestTerminalFunctional(object):
|
||||||
"*test_verbose_reporting.py::test_fail *FAIL*",
|
"*test_verbose_reporting.py::test_fail *FAIL*",
|
||||||
"*test_verbose_reporting.py::test_pass *PASS*",
|
"*test_verbose_reporting.py::test_pass *PASS*",
|
||||||
"*test_verbose_reporting.py::TestClass::test_skip *SKIP*",
|
"*test_verbose_reporting.py::TestClass::test_skip *SKIP*",
|
||||||
"*test_verbose_reporting.py::test_gen *xfail*",
|
"*test_verbose_reporting.py::test_gen *XFAIL*",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
assert result.ret == 1
|
assert result.ret == 1
|
||||||
|
|
Loading…
Reference in New Issue