test_ok1/py/test/plugin/pytest_recwarn.py

94 lines
3.0 KiB
Python

"""
provides "recwarn" funcarg for asserting warnings to be shown
to a user. See the test at the bottom for an example.
"""
import py
import os
def pytest_funcarg__recwarn(request):
""" check that warnings have been raised. """
warnings = WarningsRecorder()
request.addfinalizer(warnings.finalize)
return warnings
class RecordedWarning:
def __init__(self, message, category, filename, lineno, line):
self.message = message
self.category = category
self.filename = filename
self.lineno = lineno
self.line = line
class WarningsRecorder:
def __init__(self):
warningmodule = py.std.warnings
self.list = []
def showwarning(message, category, filename, lineno, line=0):
self.list.append(RecordedWarning(
message, category, filename, lineno, line))
try:
self.old_showwarning(message, category,
filename, lineno, line=line)
except TypeError:
# < python2.6
self.old_showwarning(message, category, filename, lineno)
self.old_showwarning = warningmodule.showwarning
warningmodule.showwarning = showwarning
def pop(self, cls=Warning):
""" pop the first recorded warning, raise exception if not exists."""
for i, w in py.builtin.enumerate(self.list):
if issubclass(w.category, cls):
return self.list.pop(i)
__tracebackhide__ = True
assert 0, "%r not found in %r" %(cls, self.list)
#def resetregistry(self):
# import warnings
# warnings.onceregistry.clear()
# warnings.__warningregistry__.clear()
def clear(self):
self.list[:] = []
def finalize(self):
py.std.warnings.showwarning = self.old_showwarning
def test_WarningRecorder():
showwarning = py.std.warnings.showwarning
rec = WarningsRecorder()
assert py.std.warnings.showwarning != showwarning
assert not rec.list
py.std.warnings.warn_explicit("hello", UserWarning, "xyz", 13)
assert len(rec.list) == 1
py.std.warnings.warn(DeprecationWarning("hello"))
assert len(rec.list) == 2
warn = rec.pop()
assert str(warn.message) == "hello"
l = rec.list
rec.clear()
assert len(rec.list) == 0
assert l is rec.list
py.test.raises(AssertionError, "rec.pop()")
rec.finalize()
assert showwarning == py.std.warnings.showwarning
def test_recwarn_functional(testdir):
sorter = testdir.inline_runsource("""
pytest_plugins = 'pytest_recwarn',
import warnings
oldwarn = warnings.showwarning
def test_method(recwarn):
assert warnings.showwarning != oldwarn
warnings.warn("hello")
warn = recwarn.pop()
assert isinstance(warn.message, UserWarning)
def test_finalized():
assert warnings.showwarning == oldwarn
""")
res = sorter.countoutcomes()
assert tuple(res) == (2, 0, 0), res