1import datetime 2import warnings 3import weakref 4import unittest 5from itertools import product 6 7 8class Test_Assertions(unittest.TestCase): 9 def test_AlmostEqual(self): 10 self.assertAlmostEqual(1.00000001, 1.0) 11 self.assertNotAlmostEqual(1.0000001, 1.0) 12 self.assertRaises(self.failureException, 13 self.assertAlmostEqual, 1.0000001, 1.0) 14 self.assertRaises(self.failureException, 15 self.assertNotAlmostEqual, 1.00000001, 1.0) 16 17 self.assertAlmostEqual(1.1, 1.0, places=0) 18 self.assertRaises(self.failureException, 19 self.assertAlmostEqual, 1.1, 1.0, places=1) 20 21 self.assertAlmostEqual(0, .1+.1j, places=0) 22 self.assertNotAlmostEqual(0, .1+.1j, places=1) 23 self.assertRaises(self.failureException, 24 self.assertAlmostEqual, 0, .1+.1j, places=1) 25 self.assertRaises(self.failureException, 26 self.assertNotAlmostEqual, 0, .1+.1j, places=0) 27 28 self.assertAlmostEqual(float('inf'), float('inf')) 29 self.assertRaises(self.failureException, self.assertNotAlmostEqual, 30 float('inf'), float('inf')) 31 32 def test_AmostEqualWithDelta(self): 33 self.assertAlmostEqual(1.1, 1.0, delta=0.5) 34 self.assertAlmostEqual(1.0, 1.1, delta=0.5) 35 self.assertNotAlmostEqual(1.1, 1.0, delta=0.05) 36 self.assertNotAlmostEqual(1.0, 1.1, delta=0.05) 37 38 self.assertAlmostEqual(1.0, 1.0, delta=0.5) 39 self.assertRaises(self.failureException, self.assertNotAlmostEqual, 40 1.0, 1.0, delta=0.5) 41 42 self.assertRaises(self.failureException, self.assertAlmostEqual, 43 1.1, 1.0, delta=0.05) 44 self.assertRaises(self.failureException, self.assertNotAlmostEqual, 45 1.1, 1.0, delta=0.5) 46 47 self.assertRaises(TypeError, self.assertAlmostEqual, 48 1.1, 1.0, places=2, delta=2) 49 self.assertRaises(TypeError, self.assertNotAlmostEqual, 50 1.1, 1.0, places=2, delta=2) 51 52 first = datetime.datetime.now() 53 second = first + datetime.timedelta(seconds=10) 54 self.assertAlmostEqual(first, second, 55 delta=datetime.timedelta(seconds=20)) 56 self.assertNotAlmostEqual(first, second, 57 delta=datetime.timedelta(seconds=5)) 58 59 def test_assertRaises(self): 60 def _raise(e): 61 raise e 62 self.assertRaises(KeyError, _raise, KeyError) 63 self.assertRaises(KeyError, _raise, KeyError("key")) 64 try: 65 self.assertRaises(KeyError, lambda: None) 66 except self.failureException as e: 67 self.assertIn("KeyError not raised", str(e)) 68 else: 69 self.fail("assertRaises() didn't fail") 70 try: 71 self.assertRaises(KeyError, _raise, ValueError) 72 except ValueError: 73 pass 74 else: 75 self.fail("assertRaises() didn't let exception pass through") 76 with self.assertRaises(KeyError) as cm: 77 try: 78 raise KeyError 79 except Exception as e: 80 exc = e 81 raise 82 self.assertIs(cm.exception, exc) 83 84 with self.assertRaises(KeyError): 85 raise KeyError("key") 86 try: 87 with self.assertRaises(KeyError): 88 pass 89 except self.failureException as e: 90 self.assertIn("KeyError not raised", str(e)) 91 else: 92 self.fail("assertRaises() didn't fail") 93 try: 94 with self.assertRaises(KeyError): 95 raise ValueError 96 except ValueError: 97 pass 98 else: 99 self.fail("assertRaises() didn't let exception pass through") 100 101 def test_assertRaises_frames_survival(self): 102 # Issue #9815: assertRaises should avoid keeping local variables 103 # in a traceback alive. 104 class A: 105 pass 106 wr = None 107 108 class Foo(unittest.TestCase): 109 110 def foo(self): 111 nonlocal wr 112 a = A() 113 wr = weakref.ref(a) 114 try: 115 raise OSError 116 except OSError: 117 raise ValueError 118 119 def test_functional(self): 120 self.assertRaises(ValueError, self.foo) 121 122 def test_with(self): 123 with self.assertRaises(ValueError): 124 self.foo() 125 126 Foo("test_functional").run() 127 self.assertIsNone(wr()) 128 Foo("test_with").run() 129 self.assertIsNone(wr()) 130 131 def testAssertNotRegex(self): 132 self.assertNotRegex('Ala ma kota', r'r+') 133 try: 134 self.assertNotRegex('Ala ma kota', r'k.t', 'Message') 135 except self.failureException as e: 136 self.assertIn('Message', e.args[0]) 137 else: 138 self.fail('assertNotRegex should have failed.') 139 140 141class TestLongMessage(unittest.TestCase): 142 """Test that the individual asserts honour longMessage. 143 This actually tests all the message behaviour for 144 asserts that use longMessage.""" 145 146 def setUp(self): 147 class TestableTestFalse(unittest.TestCase): 148 longMessage = False 149 failureException = self.failureException 150 151 def testTest(self): 152 pass 153 154 class TestableTestTrue(unittest.TestCase): 155 longMessage = True 156 failureException = self.failureException 157 158 def testTest(self): 159 pass 160 161 self.testableTrue = TestableTestTrue('testTest') 162 self.testableFalse = TestableTestFalse('testTest') 163 164 def testDefault(self): 165 self.assertTrue(unittest.TestCase.longMessage) 166 167 def test_formatMsg(self): 168 self.assertEqual(self.testableFalse._formatMessage(None, "foo"), "foo") 169 self.assertEqual(self.testableFalse._formatMessage("foo", "bar"), "foo") 170 171 self.assertEqual(self.testableTrue._formatMessage(None, "foo"), "foo") 172 self.assertEqual(self.testableTrue._formatMessage("foo", "bar"), "bar : foo") 173 174 # This blows up if _formatMessage uses string concatenation 175 self.testableTrue._formatMessage(object(), 'foo') 176 177 def test_formatMessage_unicode_error(self): 178 one = ''.join(chr(i) for i in range(255)) 179 # this used to cause a UnicodeDecodeError constructing msg 180 self.testableTrue._formatMessage(one, '\uFFFD') 181 182 def assertMessages(self, methodName, args, errors): 183 """ 184 Check that methodName(*args) raises the correct error messages. 185 errors should be a list of 4 regex that match the error when: 186 1) longMessage = False and no msg passed; 187 2) longMessage = False and msg passed; 188 3) longMessage = True and no msg passed; 189 4) longMessage = True and msg passed; 190 """ 191 def getMethod(i): 192 useTestableFalse = i < 2 193 if useTestableFalse: 194 test = self.testableFalse 195 else: 196 test = self.testableTrue 197 return getattr(test, methodName) 198 199 for i, expected_regex in enumerate(errors): 200 testMethod = getMethod(i) 201 kwargs = {} 202 withMsg = i % 2 203 if withMsg: 204 kwargs = {"msg": "oops"} 205 206 with self.assertRaisesRegex(self.failureException, 207 expected_regex=expected_regex): 208 testMethod(*args, **kwargs) 209 210 def testAssertTrue(self): 211 self.assertMessages('assertTrue', (False,), 212 ["^False is not true$", "^oops$", "^False is not true$", 213 "^False is not true : oops$"]) 214 215 def testAssertFalse(self): 216 self.assertMessages('assertFalse', (True,), 217 ["^True is not false$", "^oops$", "^True is not false$", 218 "^True is not false : oops$"]) 219 220 def testNotEqual(self): 221 self.assertMessages('assertNotEqual', (1, 1), 222 ["^1 == 1$", "^oops$", "^1 == 1$", 223 "^1 == 1 : oops$"]) 224 225 def testAlmostEqual(self): 226 self.assertMessages( 227 'assertAlmostEqual', (1, 2), 228 [r"^1 != 2 within 7 places \(1 difference\)$", "^oops$", 229 r"^1 != 2 within 7 places \(1 difference\)$", 230 r"^1 != 2 within 7 places \(1 difference\) : oops$"]) 231 232 def testNotAlmostEqual(self): 233 self.assertMessages('assertNotAlmostEqual', (1, 1), 234 ["^1 == 1 within 7 places$", "^oops$", 235 "^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"]) 236 237 def test_baseAssertEqual(self): 238 self.assertMessages('_baseAssertEqual', (1, 2), 239 ["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"]) 240 241 def testAssertSequenceEqual(self): 242 # Error messages are multiline so not testing on full message 243 # assertTupleEqual and assertListEqual delegate to this method 244 self.assertMessages('assertSequenceEqual', ([], [None]), 245 [r"\+ \[None\]$", "^oops$", r"\+ \[None\]$", 246 r"\+ \[None\] : oops$"]) 247 248 def testAssertSetEqual(self): 249 self.assertMessages('assertSetEqual', (set(), set([None])), 250 ["None$", "^oops$", "None$", 251 "None : oops$"]) 252 253 def testAssertIn(self): 254 self.assertMessages('assertIn', (None, []), 255 [r'^None not found in \[\]$', "^oops$", 256 r'^None not found in \[\]$', 257 r'^None not found in \[\] : oops$']) 258 259 def testAssertNotIn(self): 260 self.assertMessages('assertNotIn', (None, [None]), 261 [r'^None unexpectedly found in \[None\]$', "^oops$", 262 r'^None unexpectedly found in \[None\]$', 263 r'^None unexpectedly found in \[None\] : oops$']) 264 265 def testAssertDictEqual(self): 266 self.assertMessages('assertDictEqual', ({}, {'key': 'value'}), 267 [r"\+ \{'key': 'value'\}$", "^oops$", 268 r"\+ \{'key': 'value'\}$", 269 r"\+ \{'key': 'value'\} : oops$"]) 270 271 def testAssertDictContainsSubset(self): 272 with warnings.catch_warnings(): 273 warnings.simplefilter("ignore", DeprecationWarning) 274 275 self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}), 276 ["^Missing: 'key'$", "^oops$", 277 "^Missing: 'key'$", 278 "^Missing: 'key' : oops$"]) 279 280 def testAssertMultiLineEqual(self): 281 self.assertMessages('assertMultiLineEqual', ("", "foo"), 282 [r"\+ foo$", "^oops$", 283 r"\+ foo$", 284 r"\+ foo : oops$"]) 285 286 def testAssertLess(self): 287 self.assertMessages('assertLess', (2, 1), 288 ["^2 not less than 1$", "^oops$", 289 "^2 not less than 1$", "^2 not less than 1 : oops$"]) 290 291 def testAssertLessEqual(self): 292 self.assertMessages('assertLessEqual', (2, 1), 293 ["^2 not less than or equal to 1$", "^oops$", 294 "^2 not less than or equal to 1$", 295 "^2 not less than or equal to 1 : oops$"]) 296 297 def testAssertGreater(self): 298 self.assertMessages('assertGreater', (1, 2), 299 ["^1 not greater than 2$", "^oops$", 300 "^1 not greater than 2$", 301 "^1 not greater than 2 : oops$"]) 302 303 def testAssertGreaterEqual(self): 304 self.assertMessages('assertGreaterEqual', (1, 2), 305 ["^1 not greater than or equal to 2$", "^oops$", 306 "^1 not greater than or equal to 2$", 307 "^1 not greater than or equal to 2 : oops$"]) 308 309 def testAssertIsNone(self): 310 self.assertMessages('assertIsNone', ('not None',), 311 ["^'not None' is not None$", "^oops$", 312 "^'not None' is not None$", 313 "^'not None' is not None : oops$"]) 314 315 def testAssertIsNotNone(self): 316 self.assertMessages('assertIsNotNone', (None,), 317 ["^unexpectedly None$", "^oops$", 318 "^unexpectedly None$", 319 "^unexpectedly None : oops$"]) 320 321 def testAssertIs(self): 322 self.assertMessages('assertIs', (None, 'foo'), 323 ["^None is not 'foo'$", "^oops$", 324 "^None is not 'foo'$", 325 "^None is not 'foo' : oops$"]) 326 327 def testAssertIsNot(self): 328 self.assertMessages('assertIsNot', (None, None), 329 ["^unexpectedly identical: None$", "^oops$", 330 "^unexpectedly identical: None$", 331 "^unexpectedly identical: None : oops$"]) 332 333 def testAssertRegex(self): 334 self.assertMessages('assertRegex', ('foo', 'bar'), 335 ["^Regex didn't match:", 336 "^oops$", 337 "^Regex didn't match:", 338 "^Regex didn't match: (.*) : oops$"]) 339 340 def testAssertNotRegex(self): 341 self.assertMessages('assertNotRegex', ('foo', 'foo'), 342 ["^Regex matched:", 343 "^oops$", 344 "^Regex matched:", 345 "^Regex matched: (.*) : oops$"]) 346 347 348 def assertMessagesCM(self, methodName, args, func, errors): 349 """ 350 Check that the correct error messages are raised while executing: 351 with method(*args): 352 func() 353 *errors* should be a list of 4 regex that match the error when: 354 1) longMessage = False and no msg passed; 355 2) longMessage = False and msg passed; 356 3) longMessage = True and no msg passed; 357 4) longMessage = True and msg passed; 358 """ 359 p = product((self.testableFalse, self.testableTrue), 360 ({}, {"msg": "oops"})) 361 for (cls, kwargs), err in zip(p, errors): 362 method = getattr(cls, methodName) 363 with self.assertRaisesRegex(cls.failureException, err): 364 with method(*args, **kwargs) as cm: 365 func() 366 367 def testAssertRaises(self): 368 self.assertMessagesCM('assertRaises', (TypeError,), lambda: None, 369 ['^TypeError not raised$', '^oops$', 370 '^TypeError not raised$', 371 '^TypeError not raised : oops$']) 372 373 def testAssertRaisesRegex(self): 374 # test error not raised 375 self.assertMessagesCM('assertRaisesRegex', (TypeError, 'unused regex'), 376 lambda: None, 377 ['^TypeError not raised$', '^oops$', 378 '^TypeError not raised$', 379 '^TypeError not raised : oops$']) 380 # test error raised but with wrong message 381 def raise_wrong_message(): 382 raise TypeError('foo') 383 self.assertMessagesCM('assertRaisesRegex', (TypeError, 'regex'), 384 raise_wrong_message, 385 ['^"regex" does not match "foo"$', '^oops$', 386 '^"regex" does not match "foo"$', 387 '^"regex" does not match "foo" : oops$']) 388 389 def testAssertWarns(self): 390 self.assertMessagesCM('assertWarns', (UserWarning,), lambda: None, 391 ['^UserWarning not triggered$', '^oops$', 392 '^UserWarning not triggered$', 393 '^UserWarning not triggered : oops$']) 394 395 def testAssertWarnsRegex(self): 396 # test error not raised 397 self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'unused regex'), 398 lambda: None, 399 ['^UserWarning not triggered$', '^oops$', 400 '^UserWarning not triggered$', 401 '^UserWarning not triggered : oops$']) 402 # test warning raised but with wrong message 403 def raise_wrong_message(): 404 warnings.warn('foo') 405 self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'regex'), 406 raise_wrong_message, 407 ['^"regex" does not match "foo"$', '^oops$', 408 '^"regex" does not match "foo"$', 409 '^"regex" does not match "foo" : oops$']) 410 411 412if __name__ == "__main__": 413 unittest.main() 414