introduce warning system with this API:

- node.warn() for a node-specific warning
- config.warn() for a global non-node specific warning

Each warning is accompanied by a "warning number" so that we can later
introduce mechanisms for surpressing them.

Each warning will trigger a call to pytest_report_warn(number, node, message)
which is by default implemented by the TerminalReporter which introduces
a new option "-rw" to show details about warnings.
This commit is contained in:
holger krekel
2014-03-11 22:10:17 +01:00
parent b96559149c
commit 1b387bea62
5 changed files with 90 additions and 1 deletions
+5
View File
@@ -613,6 +613,11 @@ class Config(object):
self.hook.pytest_unconfigure(config=self)
self.pluginmanager.ensure_shutdown()
def warn(self, code, message):
""" generate a warning for this test session. """
self.hook.pytest_logwarning(code=code, message=message,
fslocation=None, nodeid=None)
def pytest_cmdline_parse(self, pluginmanager, args):
assert self == pluginmanager.config, (self, pluginmanager.config)
self.parse(args)
+5
View File
@@ -227,6 +227,11 @@ pytest_report_teststatus.firstresult = True
def pytest_terminal_summary(terminalreporter):
""" add additional section in terminal summary reporting. """
def pytest_logwarning(message, code, nodeid, fslocation):
""" process a warning specified by a message, a code string,
a nodeid and fslocation (both of which may be None
if the warning is not tied to a partilar node/location)."""
# -------------------------------------------------------------------------
# doctest hooks
# -------------------------------------------------------------------------
+14
View File
@@ -263,6 +263,20 @@ class Node(object):
return "<%s %r>" %(self.__class__.__name__,
getattr(self, 'name', None))
def warn(self, code, message):
""" generate a warning with the given code and message for this
item. """
assert isinstance(code, str)
fslocation = getattr(self, "location", None)
if fslocation is None:
fslocation = getattr(self, "fspath", None)
else:
fslocation = "%s:%s" % fslocation[:2]
self.ihook.pytest_logwarning(code=code, message=message,
nodeid=self.nodeid,
fslocation=fslocation)
# methods for ordering nodes
@property
def nodeid(self):
+27 -1
View File
@@ -75,6 +75,14 @@ def pytest_report_teststatus(report):
letter = "f"
return report.outcome, letter, report.outcome.upper()
class WarningReport:
def __init__(self, code, message, nodeid=None, fslocation=None):
self.code = code
self.message = message
self.nodeid = nodeid
self.fslocation = fslocation
class TerminalReporter:
def __init__(self, config, file=None):
self.config = config
@@ -151,6 +159,12 @@ class TerminalReporter:
self.write_line("INTERNALERROR> " + line)
return 1
def pytest_logwarning(self, code, fslocation, message, nodeid):
warnings = self.stats.setdefault("warnings", [])
warning = WarningReport(code=code, fslocation=fslocation,
message=message, nodeid=nodeid)
warnings.append(warning)
def pytest_plugin_registered(self, plugin):
if self.config.option.traceconfig:
msg = "PLUGIN registered: %s" % (plugin,)
@@ -335,6 +349,7 @@ class TerminalReporter:
self.summary_errors()
self.summary_failures()
self.summary_hints()
self.summary_warnings()
self.config.hook.pytest_terminal_summary(terminalreporter=self)
if exitstatus == 2:
self._report_keyboardinterrupt()
@@ -405,6 +420,16 @@ class TerminalReporter:
for hint in self.config.pluginmanager._hints:
self._tw.line("hint: %s" % hint)
def summary_warnings(self):
if self.hasopt("w"):
warnings = self.stats.get("warnings")
if not warnings:
return
self.write_sep("=", "warning summary")
for w in warnings:
self._tw.line("W%s %s %s" % (w.code,
w.fslocation, w.message))
def summary_failures(self):
if self.config.option.tbstyle != "no":
reports = self.getreports('failed')
@@ -449,7 +474,8 @@ class TerminalReporter:
def summary_stats(self):
session_duration = py.std.time.time() - self._sessionstarttime
keys = "failed passed skipped deselected xfailed xpassed".split()
keys = ("failed passed skipped deselected "
"xfailed xpassed warnings").split()
for key in self.stats.keys():
if key not in keys:
keys.append(key)