96 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
| """
 | |
| 
 | |
| "recwarn" funcarg plugin that helps to assert 
 | |
| that warnings are shown to a user.  See the test
 | |
| at the bottom for an example. 
 | |
| 
 | |
| """
 | |
| import py
 | |
| import os
 | |
| 
 | |
| class RecwarnPlugin:
 | |
|     def pytest_funcarg__recwarn(self, 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
 | |
|         
 |