1 import datetime 2 import warnings 3 import weakref 4 import unittest 5 from itertools import product 6 7 8 class 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 IOError 116 except IOError: 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 141 class 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('assertAlmostEqual', (1, 2), 227 ["^1 != 2 within 7 places$", "^oops$", 228 "^1 != 2 within 7 places$", "^1 != 2 within 7 places : oops$"]) 229 230 def testNotAlmostEqual(self): 231 self.assertMessages('assertNotAlmostEqual', (1, 1), 232 ["^1 == 1 within 7 places$", "^oops$", 233 "^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"]) 234 235 def test_baseAssertEqual(self): 236 self.assertMessages('_baseAssertEqual', (1, 2), 237 ["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"]) 238 239 def testAssertSequenceEqual(self): 240 # Error messages are multiline so not testing on full message 241 # assertTupleEqual and assertListEqual delegate to this method 242 self.assertMessages('assertSequenceEqual', ([], [None]), 243 [r"\+ \[None\]$", "^oops$", r"\+ \[None\]$", 244 r"\+ \[None\] : oops$"]) 245 246 def testAssertSetEqual(self): 247 self.assertMessages('assertSetEqual', (set(), set([None])), 248 ["None$", "^oops$", "None$", 249 "None : oops$"]) 250 251 def testAssertIn(self): 252 self.assertMessages('assertIn', (None, []), 253 [r'^None not found in \[\]$', "^oops$", 254 r'^None not found in \[\]$', 255 r'^None not found in \[\] : oops$']) 256 257 def testAssertNotIn(self): 258 self.assertMessages('assertNotIn', (None, [None]), 259 [r'^None unexpectedly found in \[None\]$', "^oops$", 260 r'^None unexpectedly found in \[None\]$', 261 r'^None unexpectedly found in \[None\] : oops$']) 262 263 def testAssertDictEqual(self): 264 self.assertMessages('assertDictEqual', ({}, {'key': 'value'}), 265 [r"\+ \{'key': 'value'\}$", "^oops$", 266 r"\+ \{'key': 'value'\}$", 267 r"\+ \{'key': 'value'\} : oops$"]) 268 269 def testAssertDictContainsSubset(self): 270 with warnings.catch_warnings(): 271 warnings.simplefilter("ignore", DeprecationWarning) 272 273 self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}), 274 ["^Missing: 'key'$", "^oops$", 275 "^Missing: 'key'$", 276 "^Missing: 'key' : oops$"]) 277 278 def testAssertMultiLineEqual(self): 279 self.assertMessages('assertMultiLineEqual', ("", "foo"), 280 [r"\+ foo$", "^oops$", 281 r"\+ foo$", 282 r"\+ foo : oops$"]) 283 284 def testAssertLess(self): 285 self.assertMessages('assertLess', (2, 1), 286 ["^2 not less than 1$", "^oops$", 287 "^2 not less than 1$", "^2 not less than 1 : oops$"]) 288 289 def testAssertLessEqual(self): 290 self.assertMessages('assertLessEqual', (2, 1), 291 ["^2 not less than or equal to 1$", "^oops$", 292 "^2 not less than or equal to 1$", 293 "^2 not less than or equal to 1 : oops$"]) 294 295 def testAssertGreater(self): 296 self.assertMessages('assertGreater', (1, 2), 297 ["^1 not greater than 2$", "^oops$", 298 "^1 not greater than 2$", 299 "^1 not greater than 2 : oops$"]) 300 301 def testAssertGreaterEqual(self): 302 self.assertMessages('assertGreaterEqual', (1, 2), 303 ["^1 not greater than or equal to 2$", "^oops$", 304 "^1 not greater than or equal to 2$", 305 "^1 not greater than or equal to 2 : oops$"]) 306 307 def testAssertIsNone(self): 308 self.assertMessages('assertIsNone', ('not None',), 309 ["^'not None' is not None$", "^oops$", 310 "^'not None' is not None$", 311 "^'not None' is not None : oops$"]) 312 313 def testAssertIsNotNone(self): 314 self.assertMessages('assertIsNotNone', (None,), 315 ["^unexpectedly None$", "^oops$", 316 "^unexpectedly None$", 317 "^unexpectedly None : oops$"]) 318 319 def testAssertIs(self): 320 self.assertMessages('assertIs', (None, 'foo'), 321 ["^None is not 'foo'$", "^oops$", 322 "^None is not 'foo'$", 323 "^None is not 'foo' : oops$"]) 324 325 def testAssertIsNot(self): 326 self.assertMessages('assertIsNot', (None, None), 327 ["^unexpectedly identical: None$", "^oops$", 328 "^unexpectedly identical: None$", 329 "^unexpectedly identical: None : oops$"]) 330 331 def testAssertRegex(self): 332 self.assertMessages('assertRegex', ('foo', 'bar'), 333 ["^Regex didn't match:", 334 "^oops$", 335 "^Regex didn't match:", 336 "^Regex didn't match: (.*) : oops$"]) 337 338 def testAssertNotRegex(self): 339 self.assertMessages('assertNotRegex', ('foo', 'foo'), 340 ["^Regex matched:", 341 "^oops$", 342 "^Regex matched:", 343 "^Regex matched: (.*) : oops$"]) 344 345 346 def assertMessagesCM(self, methodName, args, func, errors): 347 """ 348 Check that the correct error messages are raised while executing: 349 with method(*args): 350 func() 351 *errors* should be a list of 4 regex that match the error when: 352 1) longMessage = False and no msg passed; 353 2) longMessage = False and msg passed; 354 3) longMessage = True and no msg passed; 355 4) longMessage = True and msg passed; 356 """ 357 p = product((self.testableFalse, self.testableTrue), 358 ({}, {"msg": "oops"})) 359 for (cls, kwargs), err in zip(p, errors): 360 method = getattr(cls, methodName) 361 with self.assertRaisesRegex(cls.failureException, err): 362 with method(*args, **kwargs) as cm: 363 func() 364 365 def testAssertRaises(self): 366 self.assertMessagesCM('assertRaises', (TypeError,), lambda: None, 367 ['^TypeError not raised$', '^oops$', 368 '^TypeError not raised$', 369 '^TypeError not raised : oops$']) 370 371 def testAssertRaisesRegex(self): 372 # test error not raised 373 self.assertMessagesCM('assertRaisesRegex', (TypeError, 'unused regex'), 374 lambda: None, 375 ['^TypeError not raised$', '^oops$', 376 '^TypeError not raised$', 377 '^TypeError not raised : oops$']) 378 # test error raised but with wrong message 379 def raise_wrong_message(): 380 raise TypeError('foo') 381 self.assertMessagesCM('assertRaisesRegex', (TypeError, 'regex'), 382 raise_wrong_message, 383 ['^"regex" does not match "foo"$', '^oops$', 384 '^"regex" does not match "foo"$', 385 '^"regex" does not match "foo" : oops$']) 386 387 def testAssertWarns(self): 388 self.assertMessagesCM('assertWarns', (UserWarning,), lambda: None, 389 ['^UserWarning not triggered$', '^oops$', 390 '^UserWarning not triggered$', 391 '^UserWarning not triggered : oops$']) 392 393 def testAssertWarnsRegex(self): 394 # test error not raised 395 self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'unused regex'), 396 lambda: None, 397 ['^UserWarning not triggered$', '^oops$', 398 '^UserWarning not triggered$', 399 '^UserWarning not triggered : oops$']) 400 # test warning raised but with wrong message 401 def raise_wrong_message(): 402 warnings.warn('foo') 403 self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'regex'), 404 raise_wrong_message, 405 ['^"regex" does not match "foo"$', '^oops$', 406 '^"regex" does not match "foo"$', 407 '^"regex" does not match "foo" : oops$']) 408 409 410 if __name__ == "__main__": 411 unittest.main() 412