Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(179380)

Delta Between Two Patch Sets: Lib/unittest/test/test_case.py

Issue 18937: add unittest assertion for logging
Left Patch Set: Created 5 years, 10 months ago
Right Patch Set: Created 5 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/unittest/case.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 import contextlib 1 import contextlib
2 import difflib 2 import difflib
3 import pprint 3 import pprint
4 import pickle 4 import pickle
5 import re 5 import re
6 import sys 6 import sys
7 import logging 7 import logging
8 import warnings 8 import warnings
9 import weakref 9 import weakref
10 import inspect 10 import inspect
11 11
12 from copy import deepcopy 12 from copy import deepcopy
13 from test import support 13 from test import support
14 14
15 import unittest 15 import unittest
16 16
17 from .support import ( 17 from .support import (
18 TestEquality, TestHashing, LoggingResult, LegacyLoggingResult, 18 TestEquality, TestHashing, LoggingResult, LegacyLoggingResult,
19 ResultWithNoStartTestRunStopTestRun 19 ResultWithNoStartTestRunStopTestRun
20 ) 20 )
21 from test.support import captured_stderr 21 from test.support import captured_stderr
22
23
24 log_foo = logging.getLogger('foo')
25 log_foobar = logging.getLogger('foo.bar')
26 log_quux = logging.getLogger('quux')
22 27
23 28
24 class Test(object): 29 class Test(object):
25 "Keep these TestCase classes out of the main namespace" 30 "Keep these TestCase classes out of the main namespace"
26 31
27 class Foo(unittest.TestCase): 32 class Foo(unittest.TestCase):
28 def runTest(self): pass 33 def runTest(self): pass
29 def test1(self): pass 34 def test1(self): pass
30 35
31 class Bar(Foo): 36 class Bar(Foo):
(...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 # check for some of them. It is implementation-defined whether 1253 # check for some of them. It is implementation-defined whether
1249 # non-matching RuntimeWarnings are simply re-raised, or produce a 1254 # non-matching RuntimeWarnings are simply re-raised, or produce a
1250 # failureException. 1255 # failureException.
1251 with warnings.catch_warnings(): 1256 with warnings.catch_warnings():
1252 warnings.simplefilter("error", RuntimeWarning) 1257 warnings.simplefilter("error", RuntimeWarning)
1253 with self.assertRaises((RuntimeWarning, self.failureException)): 1258 with self.assertRaises((RuntimeWarning, self.failureException)):
1254 with self.assertWarnsRegex(RuntimeWarning, "o+"): 1259 with self.assertWarnsRegex(RuntimeWarning, "o+"):
1255 _runtime_warn("barz") 1260 _runtime_warn("barz")
1256 1261
1257 @contextlib.contextmanager 1262 @contextlib.contextmanager
1258 def _assertNoStderr(self): 1263 def assertNoStderr(self):
1259 with captured_stderr() as buf: 1264 with captured_stderr() as buf:
1260 yield 1265 yield
1261 self.assertEqual(buf.getvalue(), "") 1266 self.assertEqual(buf.getvalue(), "")
1262 1267
1263 def _assertLogRecords(self, records, matches): 1268 def assertLogRecords(self, records, matches):
1264 self.assertEqual(len(records), len(matches)) 1269 self.assertEqual(len(records), len(matches))
1265 for rec, match in zip(records, matches): 1270 for rec, match in zip(records, matches):
1266 self.assertIsInstance(rec, logging.LogRecord) 1271 self.assertIsInstance(rec, logging.LogRecord)
1267 for k, v in match.items(): 1272 for k, v in match.items():
1268 self.assertEqual(getattr(rec, k), v) 1273 self.assertEqual(getattr(rec, k), v)
1269 1274
1270 def testAssertLogs(self): 1275 def testAssertLogsDefaults(self):
1271 log_foo = logging.getLogger('foo')
1272 log_foobar = logging.getLogger('foo.bar')
1273 log_quux = logging.getLogger('quux')
1274 # defaults: root logger, level INFO 1276 # defaults: root logger, level INFO
1275 with self._assertNoStderr(): 1277 with self.assertNoStderr():
1276 with self.assertLogs() as cm: 1278 with self.assertLogs() as cm:
1277 log_foo.info("1") 1279 log_foo.info("1")
1278 log_foobar.debug("2") 1280 log_foobar.debug("2")
1279 self.assertEqual(cm.output, ["INFO:foo:1"]) 1281 self.assertEqual(cm.output, ["INFO:foo:1"])
1280 self._assertLogRecords(cm.records, [{'name': 'foo'}]) 1282 self.assertLogRecords(cm.records, [{'name': 'foo'}])
1283
1284 def testAssertLogsTwoMatchingMessages(self):
1281 # Same, but with two matching log messages 1285 # Same, but with two matching log messages
1282 with self._assertNoStderr(): 1286 with self.assertNoStderr():
1283 with self.assertLogs() as cm: 1287 with self.assertLogs() as cm:
1284 log_foo.info("1") 1288 log_foo.info("1")
1285 log_foobar.debug("2") 1289 log_foobar.debug("2")
1286 log_quux.warning("3") 1290 log_quux.warning("3")
1287 self.assertEqual(cm.output, ["INFO:foo:1", "WARNING:quux:3"]) 1291 self.assertEqual(cm.output, ["INFO:foo:1", "WARNING:quux:3"])
1288 self._assertLogRecords(cm.records, 1292 self.assertLogRecords(cm.records,
1289 [{'name': 'foo'}, {'name': 'quux'}]) 1293 [{'name': 'foo'}, {'name': 'quux'}])
1294
1295 def checkAssertLogsPerLevel(self, level):
1296 # Check level filtering
1297 with self.assertNoStderr():
1298 with self.assertLogs(level=level) as cm:
1299 log_foo.warning("1")
1300 log_foobar.error("2")
1301 log_quux.critical("3")
1302 self.assertEqual(cm.output, ["ERROR:foo.bar:2", "CRITICAL:quux:3"])
1303 self.assertLogRecords(cm.records,
1304 [{'name': 'foo.bar'}, {'name': 'quux'}])
1305
1306 def testAssertLogsPerLevel(self):
1307 self.checkAssertLogsPerLevel(logging.ERROR)
1308 self.checkAssertLogsPerLevel('ERROR')
1309
1310 def checkAssertLogsPerLogger(self, logger):
1290 # Check per-logger fitering 1311 # Check per-logger fitering
1291 with self._assertNoStderr(): 1312 with self.assertNoStderr():
1292 with self.assertLogs(level='DEBUG') as outer_cm: 1313 with self.assertLogs(level='DEBUG') as outer_cm:
1293 with self.assertLogs('foo', level='DEBUG') as cm: 1314 with self.assertLogs(logger, level='DEBUG') as cm:
1294 log_foo.info("1") 1315 log_foo.info("1")
1295 log_foobar.debug("2") 1316 log_foobar.debug("2")
1296 log_quux.warning("3") 1317 log_quux.warning("3")
1297 self.assertEqual(cm.output, ["INFO:foo:1", "DEBUG:foo.bar:2"]) 1318 self.assertEqual(cm.output, ["INFO:foo:1", "DEBUG:foo.bar:2"])
1298 self._assertLogRecords(cm.records, 1319 self.assertLogRecords(cm.records,
1299 [{'name': 'foo'}, {'name': 'foo.bar'}]) 1320 [{'name': 'foo'}, {'name': 'foo.bar'}])
1300 # The outer catchall caught the quux log 1321 # The outer catchall caught the quux log
1301 self.assertEqual(outer_cm.output, ["WARNING:quux:3"]) 1322 self.assertEqual(outer_cm.output, ["WARNING:quux:3"])
1302 # Check level filtering 1323
1303 with self._assertNoStderr(): 1324 def testAssertLogsPerLogger(self):
1304 with self.assertLogs(level='ERROR') as cm: 1325 self.checkAssertLogsPerLogger(logging.getLogger('foo'))
1305 log_foo.warning("1") 1326 self.checkAssertLogsPerLogger('foo')
1306 log_foobar.error("2") 1327
1307 log_quux.critical("3") 1328 def testAssertLogsFailureNoLogs(self):
1308 self.assertEqual(cm.output, ["ERROR:foo.bar:2", "CRITICAL:quux:3"])
1309 self._assertLogRecords(cm.records,
1310 [{'name': 'foo.bar'}, {'name': 'quux'}])
1311 # Failure due to no logs 1329 # Failure due to no logs
1312 with self._assertNoStderr(): 1330 with self.assertNoStderr():
1313 with self.assertRaises(self.failureException): 1331 with self.assertRaises(self.failureException):
1314 with self.assertLogs(): 1332 with self.assertLogs():
1315 pass 1333 pass
1334
1335 def testAssertLogsFailureLevelTooHigh(self):
1316 # Failure due to level too high 1336 # Failure due to level too high
1317 with self._assertNoStderr(): 1337 with self.assertNoStderr():
1318 with self.assertRaises(self.failureException): 1338 with self.assertRaises(self.failureException):
1319 with self.assertLogs(level='WARNING'): 1339 with self.assertLogs(level='WARNING'):
1320 log_foo.info("1") 1340 log_foo.info("1")
1341
1342 def testAssertLogsFailureMismatchingLogger(self):
1321 # Failure due to mismatching logger (and the logged message is 1343 # Failure due to mismatching logger (and the logged message is
1322 # passed through) 1344 # passed through)
1323 with self.assertLogs('quux', level='ERROR'): 1345 with self.assertLogs('quux', level='ERROR'):
1324 with self.assertRaises(self.failureException): 1346 with self.assertRaises(self.failureException):
1325 with self.assertLogs('foo'): 1347 with self.assertLogs('foo'):
1326 log_quux.error("1") 1348 log_quux.error("1")
1327 1349
1328 def testDeprecatedMethodNames(self): 1350 def testDeprecatedMethodNames(self):
1329 """ 1351 """
1330 Test that the deprecated methods raise a DeprecationWarning. See #9424. 1352 Test that the deprecated methods raise a DeprecationWarning. See #9424.
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 self.assertEqual(len(result.errors), 1) 1494 self.assertEqual(len(result.errors), 1)
1473 self.assertEqual(result.testsRun, 1) 1495 self.assertEqual(result.testsRun, 1)
1474 1496
1475 @support.cpython_only 1497 @support.cpython_only
1476 def testNoCycles(self): 1498 def testNoCycles(self):
1477 case = unittest.TestCase() 1499 case = unittest.TestCase()
1478 wr = weakref.ref(case) 1500 wr = weakref.ref(case)
1479 with support.disable_gc(): 1501 with support.disable_gc():
1480 del case 1502 del case
1481 self.assertFalse(wr()) 1503 self.assertFalse(wr())
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+