LEFT | RIGHT |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 ''' | 2 ''' |
3 Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's | 3 Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's |
4 Smalltalk testing framework. | 4 Smalltalk testing framework. |
5 | 5 |
6 This module contains the core framework classes that form the basis of | 6 This module contains the core framework classes that form the basis of |
7 specific test cases and suites (TestCase, TestSuite etc.), and also a | 7 specific test cases and suites (TestCase, TestSuite etc.), and also a |
8 text-based utility class for running the tests and reporting the results | 8 text-based utility class for running the tests and reporting the results |
9 (TextTestRunner). | 9 (TextTestRunner). |
10 | 10 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 len(self.failures)) | 254 len(self.failures)) |
255 | 255 |
256 | 256 |
257 class _AssertRaisesContext(object): | 257 class _AssertRaisesContext(object): |
258 """A context manager used to implement TestCase.assertRaises* methods.""" | 258 """A context manager used to implement TestCase.assertRaises* methods.""" |
259 | 259 |
260 def __init__(self, expected, test_case, expected_regexp=None): | 260 def __init__(self, expected, test_case, expected_regexp=None): |
261 self.expected = expected | 261 self.expected = expected |
262 self.failureException = test_case.failureException | 262 self.failureException = test_case.failureException |
263 self.expected_regex = expected_regexp | 263 self.expected_regex = expected_regexp |
264 | 264 |
265 def __enter__(self): | 265 def __enter__(self): |
266 pass | 266 pass |
267 | 267 |
268 def __exit__(self, exc_type, exc_value, traceback): | 268 def __exit__(self, exc_type, exc_value, traceback): |
269 if exc_type is None: | 269 if exc_type is None: |
270 try: | 270 try: |
271 exc_name = self.expected.__name__ | 271 exc_name = self.expected.__name__ |
272 except AttributeError: | 272 except AttributeError: |
273 exc_name = str(self.expected) | 273 exc_name = str(self.expected) |
274 raise self.failureException( | 274 raise self.failureException( |
275 "{0} not raised".format(exc_name)) | 275 "{0} not raised".format(exc_name)) |
276 if not issubclass(exc_type, self.expected): | 276 if not issubclass(exc_type, self.expected): |
277 # let unexpexted exceptions pass through | 277 # let unexpexted exceptions pass through |
278 return False | 278 return False |
279 if self.expected_regex is None: | 279 if self.expected_regex is None: |
280 return True | 280 return True |
281 | 281 |
282 expected_regexp = self.expected_regex | 282 expected_regexp = self.expected_regex |
283 if isinstance(expected_regexp, basestring): | 283 if isinstance(expected_regexp, basestring): |
284 expected_regexp = re.compile(expected_regexp) | 284 expected_regexp = re.compile(expected_regexp) |
285 if not expected_regexp.search(str(exc_value)): | 285 if not expected_regexp.search(str(exc_value)): |
286 raise self.failureException('"%s" does not match "%s"' % | 286 raise self.failureException('"%s" does not match "%s"' % |
287 (expected_regexp.pattern, str(exc_value))) | 287 (expected_regexp.pattern, str(exc_value))) |
288 return True | 288 return True |
289 | 289 |
290 | 290 |
291 | 291 |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 do_something() | 492 do_something() |
493 """ | 493 """ |
494 context = _AssertRaisesContext(excClass, self) | 494 context = _AssertRaisesContext(excClass, self) |
495 if callableObj is None: | 495 if callableObj is None: |
496 return context | 496 return context |
497 with context: | 497 with context: |
498 callableObj(*args, **kwargs) | 498 callableObj(*args, **kwargs) |
499 | 499 |
500 def _getAssertEqualityFunc(self, first, second): | 500 def _getAssertEqualityFunc(self, first, second): |
501 """Get a detailed comparison function for the types of the two args. | 501 """Get a detailed comparison function for the types of the two args. |
502 | 502 |
503 Returns: A callable accepting (first, second, msg=None) that will | 503 Returns: A callable accepting (first, second, msg=None) that will |
504 raise a failure exception if first != second with a useful human | 504 raise a failure exception if first != second with a useful human |
505 readable error message for those types. | 505 readable error message for those types. |
506 """ | 506 """ |
507 # | 507 # |
508 # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) | 508 # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) |
509 # and vice versa. I opted for the conservative approach in case | 509 # and vice versa. I opted for the conservative approach in case |
510 # subclasses are not intended to be compared in detail to their super | 510 # subclasses are not intended to be compared in detail to their super |
511 # class instances using a type equality func. This means testing | 511 # class instances using a type equality func. This means testing |
512 # subtypes won't automagically use the detailed comparison. Callers | 512 # subtypes won't automagically use the detailed comparison. Callers |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 seq1: The first sequence to compare. | 589 seq1: The first sequence to compare. |
590 seq2: The second sequence to compare. | 590 seq2: The second sequence to compare. |
591 seq_type: The expected datatype of the sequences, or None if no | 591 seq_type: The expected datatype of the sequences, or None if no |
592 datatype should be enforced. | 592 datatype should be enforced. |
593 msg: Optional message to use on failure instead of a list of | 593 msg: Optional message to use on failure instead of a list of |
594 differences. | 594 differences. |
595 """ | 595 """ |
596 if seq_type != None: | 596 if seq_type != None: |
597 seq_type_name = seq_type.__name__ | 597 seq_type_name = seq_type.__name__ |
598 if not isinstance(seq1, seq_type): | 598 if not isinstance(seq1, seq_type): |
599 raise self.failureException('First sequence is not a %s: %r' | 599 raise self.failureException('First sequence is not a %s: %r' |
600 % (seq_type_name, seq1)) | 600 % (seq_type_name, seq1)) |
601 if not isinstance(seq2, seq_type): | 601 if not isinstance(seq2, seq_type): |
602 raise self.failureException('Second sequence is not a %s: %r' | 602 raise self.failureException('Second sequence is not a %s: %r' |
603 % (seq_type_name, seq2)) | 603 % (seq_type_name, seq2)) |
604 else: | 604 else: |
605 seq_type_name = "sequence" | 605 seq_type_name = "sequence" |
606 | 606 |
607 differing = None | 607 differing = None |
608 try: | 608 try: |
609 len1 = len(seq1) | 609 len1 = len(seq1) |
610 except (TypeError, NotImplementedError): | 610 except (TypeError, NotImplementedError): |
611 differing = 'First %s has no length. Non-sequence?' % ( | 611 differing = 'First %s has no length. Non-sequence?' % ( |
612 seq_type_name) | 612 seq_type_name) |
(...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 | 1467 |
1468 main = TestProgram | 1468 main = TestProgram |
1469 | 1469 |
1470 | 1470 |
1471 ############################################################################## | 1471 ############################################################################## |
1472 # Executing this module from the command line | 1472 # Executing this module from the command line |
1473 ############################################################################## | 1473 ############################################################################## |
1474 | 1474 |
1475 if __name__ == "__main__": | 1475 if __name__ == "__main__": |
1476 main(module=None) | 1476 main(module=None) |
LEFT | RIGHT |