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

Side by Side Diff: Lib/unittest/test/test_case.py

Issue 18937: add unittest assertion for logging
Patch Set: Created 6 years 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:
View unified diff | Download patch
« no previous file with comments | « Lib/unittest/case.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 import contextlib
1 import difflib 2 import difflib
2 import pprint 3 import pprint
3 import pickle 4 import pickle
4 import re 5 import re
5 import sys 6 import sys
7 import logging
6 import warnings 8 import warnings
7 import weakref 9 import weakref
8 import inspect 10 import inspect
9 11
10 from copy import deepcopy 12 from copy import deepcopy
11 from test import support 13 from test import support
12 14
13 import unittest 15 import unittest
14 16
15 from .support import ( 17 from .support import (
16 TestEquality, TestHashing, LoggingResult, LegacyLoggingResult, 18 TestEquality, TestHashing, LoggingResult, LegacyLoggingResult,
17 ResultWithNoStartTestRunStopTestRun 19 ResultWithNoStartTestRunStopTestRun
18 ) 20 )
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')
19 27
20 28
21 class Test(object): 29 class Test(object):
22 "Keep these TestCase classes out of the main namespace" 30 "Keep these TestCase classes out of the main namespace"
23 31
24 class Foo(unittest.TestCase): 32 class Foo(unittest.TestCase):
25 def runTest(self): pass 33 def runTest(self): pass
26 def test1(self): pass 34 def test1(self): pass
27 35
28 class Bar(Foo): 36 class Bar(Foo):
(...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 _runtime_warn("barz") 1251 _runtime_warn("barz")
1244 # A little trickier: we ask RuntimeWarnings to be raised, and then 1252 # A little trickier: we ask RuntimeWarnings to be raised, and then
1245 # check for some of them. It is implementation-defined whether 1253 # check for some of them. It is implementation-defined whether
1246 # non-matching RuntimeWarnings are simply re-raised, or produce a 1254 # non-matching RuntimeWarnings are simply re-raised, or produce a
1247 # failureException. 1255 # failureException.
1248 with warnings.catch_warnings(): 1256 with warnings.catch_warnings():
1249 warnings.simplefilter("error", RuntimeWarning) 1257 warnings.simplefilter("error", RuntimeWarning)
1250 with self.assertRaises((RuntimeWarning, self.failureException)): 1258 with self.assertRaises((RuntimeWarning, self.failureException)):
1251 with self.assertWarnsRegex(RuntimeWarning, "o+"): 1259 with self.assertWarnsRegex(RuntimeWarning, "o+"):
1252 _runtime_warn("barz") 1260 _runtime_warn("barz")
1261
1262 @contextlib.contextmanager
1263 def assertNoStderr(self):
1264 with captured_stderr() as buf:
1265 yield
1266 self.assertEqual(buf.getvalue(), "")
1267
1268 def assertLogRecords(self, records, matches):
1269 self.assertEqual(len(records), len(matches))
1270 for rec, match in zip(records, matches):
1271 self.assertIsInstance(rec, logging.LogRecord)
1272 for k, v in match.items():
1273 self.assertEqual(getattr(rec, k), v)
1274
1275 def testAssertLogsDefaults(self):
1276 # defaults: root logger, level INFO
1277 with self.assertNoStderr():
1278 with self.assertLogs() as cm:
1279 log_foo.info("1")
1280 log_foobar.debug("2")
1281 self.assertEqual(cm.output, ["INFO:foo:1"])
1282 self.assertLogRecords(cm.records, [{'name': 'foo'}])
1283
1284 def testAssertLogsTwoMatchingMessages(self):
1285 # Same, but with two matching log messages
1286 with self.assertNoStderr():
1287 with self.assertLogs() as cm:
1288 log_foo.info("1")
1289 log_foobar.debug("2")
1290 log_quux.warning("3")
1291 self.assertEqual(cm.output, ["INFO:foo:1", "WARNING:quux:3"])
1292 self.assertLogRecords(cm.records,
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):
1311 # Check per-logger fitering
1312 with self.assertNoStderr():
1313 with self.assertLogs(level='DEBUG') as outer_cm:
1314 with self.assertLogs(logger, level='DEBUG') as cm:
1315 log_foo.info("1")
1316 log_foobar.debug("2")
1317 log_quux.warning("3")
1318 self.assertEqual(cm.output, ["INFO:foo:1", "DEBUG:foo.bar:2"])
1319 self.assertLogRecords(cm.records,
1320 [{'name': 'foo'}, {'name': 'foo.bar'}])
1321 # The outer catchall caught the quux log
1322 self.assertEqual(outer_cm.output, ["WARNING:quux:3"])
1323
1324 def testAssertLogsPerLogger(self):
1325 self.checkAssertLogsPerLogger(logging.getLogger('foo'))
1326 self.checkAssertLogsPerLogger('foo')
1327
1328 def testAssertLogsFailureNoLogs(self):
1329 # Failure due to no logs
1330 with self.assertNoStderr():
1331 with self.assertRaises(self.failureException):
1332 with self.assertLogs():
1333 pass
1334
1335 def testAssertLogsFailureLevelTooHigh(self):
1336 # Failure due to level too high
1337 with self.assertNoStderr():
1338 with self.assertRaises(self.failureException):
1339 with self.assertLogs(level='WARNING'):
1340 log_foo.info("1")
1341
1342 def testAssertLogsFailureMismatchingLogger(self):
1343 # Failure due to mismatching logger (and the logged message is
1344 # passed through)
1345 with self.assertLogs('quux', level='ERROR'):
1346 with self.assertRaises(self.failureException):
1347 with self.assertLogs('foo'):
1348 log_quux.error("1")
1253 1349
1254 def testDeprecatedMethodNames(self): 1350 def testDeprecatedMethodNames(self):
1255 """ 1351 """
1256 Test that the deprecated methods raise a DeprecationWarning. See #9424. 1352 Test that the deprecated methods raise a DeprecationWarning. See #9424.
1257 """ 1353 """
1258 old = ( 1354 old = (
1259 (self.failIfEqual, (3, 5)), 1355 (self.failIfEqual, (3, 5)),
1260 (self.assertNotEquals, (3, 5)), 1356 (self.assertNotEquals, (3, 5)),
1261 (self.failUnlessEqual, (3, 3)), 1357 (self.failUnlessEqual, (3, 3)),
1262 (self.assertEquals, (3, 3)), 1358 (self.assertEquals, (3, 3)),
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1398 self.assertEqual(len(result.errors), 1) 1494 self.assertEqual(len(result.errors), 1)
1399 self.assertEqual(result.testsRun, 1) 1495 self.assertEqual(result.testsRun, 1)
1400 1496
1401 @support.cpython_only 1497 @support.cpython_only
1402 def testNoCycles(self): 1498 def testNoCycles(self):
1403 case = unittest.TestCase() 1499 case = unittest.TestCase()
1404 wr = weakref.ref(case) 1500 wr = weakref.ref(case)
1405 with support.disable_gc(): 1501 with support.disable_gc():
1406 del case 1502 del case
1407 self.assertFalse(wr()) 1503 self.assertFalse(wr())
OLDNEW
« no previous file with comments | « Lib/unittest/case.py ('k') | no next file » | no next file with comments »

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