175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen"""Test result object""" 275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport sys 475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport traceback 575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport unittest 675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenfrom StringIO import StringIO 875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenfrom unittest2 import util 1075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenfrom unittest2.compatibility import wraps 1175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 1275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen__unittest = True 1375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 1475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chendef failfast(method): 1575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen @wraps(method) 1675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def inner(self, *args, **kw): 1775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if getattr(self, 'failfast', False): 1875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.stop() 1975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen return method(self, *args, **kw) 2075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen return inner 2175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 2275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 2375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny ChenSTDOUT_LINE = '\nStdout:\n%s' 2475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny ChenSTDERR_LINE = '\nStderr:\n%s' 2575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 2675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass TestResult(unittest.TestResult): 2775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Holder for test result information. 2875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 2975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen Test results are automatically managed by the TestCase and TestSuite 3075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen classes, and do not need to be explicitly manipulated by writers of tests. 3175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 3275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen Each instance holds the total number of tests run, and collections of 3375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen failures and errors that occurred among those test runs. The collections 3475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen contain tuples of (testcase, exceptioninfo), where exceptioninfo is the 3575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen formatted traceback of the error that occurred. 3675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """ 3775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen _previousTestClass = None 3875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen _moduleSetUpFailed = False 3975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 4075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def __init__(self): 4175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.failfast = False 4275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.failures = [] 4375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.errors = [] 4475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.testsRun = 0 4575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.skipped = [] 4675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.expectedFailures = [] 4775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.unexpectedSuccesses = [] 4875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.shouldStop = False 4975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.buffer = False 5075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._stdout_buffer = None 5175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._stderr_buffer = None 5275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._original_stdout = sys.stdout 5375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._original_stderr = sys.stderr 5475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._mirrorOutput = False 5575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 5675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def startTest(self, test): 5775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen "Called when the given test is about to be run" 5875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.testsRun += 1 5975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._mirrorOutput = False 6075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if self.buffer: 6175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if self._stderr_buffer is None: 6275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._stderr_buffer = StringIO() 6375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._stdout_buffer = StringIO() 6475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen sys.stdout = self._stdout_buffer 6575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen sys.stderr = self._stderr_buffer 6675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 6775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def startTestRun(self): 6875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Called once before any tests are executed. 6975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 7075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen See startTest for a method called before each test. 7175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """ 7275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 7375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def stopTest(self, test): 7475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Called when the given test has been run""" 7575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if self.buffer: 7675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if self._mirrorOutput: 7775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen output = sys.stdout.getvalue() 7875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen error = sys.stderr.getvalue() 7975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if output: 8075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if not output.endswith('\n'): 8175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen output += '\n' 8275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._original_stdout.write(STDOUT_LINE % output) 8375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if error: 8475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if not error.endswith('\n'): 8575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen error += '\n' 8675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._original_stderr.write(STDERR_LINE % error) 8775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 8875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen sys.stdout = self._original_stdout 8975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen sys.stderr = self._original_stderr 9075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._stdout_buffer.seek(0) 9175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._stdout_buffer.truncate() 9275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._stderr_buffer.seek(0) 9375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._stderr_buffer.truncate() 9475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._mirrorOutput = False 9575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 9675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 9775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def stopTestRun(self): 9875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Called once after all tests are executed. 9975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 10075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen See stopTest for a method called after each test. 10175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """ 10275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 10375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen @failfast 10475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def addError(self, test, err): 10575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Called when an error has occurred. 'err' is a tuple of values as 10675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen returned by sys.exc_info(). 10775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """ 10875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.errors.append((test, self._exc_info_to_string(err, test))) 10975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._mirrorOutput = True 11075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 11175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen @failfast 11275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def addFailure(self, test, err): 11375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Called when an error has occurred. 'err' is a tuple of values as 11475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen returned by sys.exc_info().""" 11575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.failures.append((test, self._exc_info_to_string(err, test))) 11675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self._mirrorOutput = True 11775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 11875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def addSuccess(self, test): 11975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen "Called when a test has completed successfully" 12075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen pass 12175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 12275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def addSkip(self, test, reason): 12375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Called when a test is skipped.""" 12475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.skipped.append((test, reason)) 12575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 12621416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata def addExpectedFailure(self, test, err, bugnumber): 12775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Called when an expected failure/error occured.""" 12875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.expectedFailures.append( 12975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen (test, self._exc_info_to_string(err, test))) 13075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 13175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen @failfast 13221416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata def addUnexpectedSuccess(self, test, bugnumber): 13375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Called when a test was expected to fail, but succeed.""" 13475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.unexpectedSuccesses.append(test) 13575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 13675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def wasSuccessful(self): 13775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen "Tells whether or not this result was a success" 13875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen return (len(self.failures) + len(self.errors) == 0) 13975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 14075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def stop(self): 14175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen "Indicates that the tests should be aborted" 14275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen self.shouldStop = True 14375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 14475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def _exc_info_to_string(self, err, test): 14575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen """Converts a sys.exc_info()-style tuple of values into a string.""" 14675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen exctype, value, tb = err 14775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen # Skip test runner traceback levels 14875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen while tb and self._is_relevant_tb_level(tb): 14975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen tb = tb.tb_next 15075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if exctype is test.failureException: 15175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen # Skip assert*() traceback levels 15275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen length = self._count_relevant_tb_levels(tb) 15375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen msgLines = traceback.format_exception(exctype, value, tb, length) 15475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen else: 15575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen msgLines = traceback.format_exception(exctype, value, tb) 15675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 15775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if self.buffer: 15875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen output = sys.stdout.getvalue() 15975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen error = sys.stderr.getvalue() 16075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if output: 16175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if not output.endswith('\n'): 16275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen output += '\n' 16375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen msgLines.append(STDOUT_LINE % output) 16475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if error: 16575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen if not error.endswith('\n'): 16675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen error += '\n' 16775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen msgLines.append(STDERR_LINE % error) 16875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen return ''.join(msgLines) 16975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 17075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def _is_relevant_tb_level(self, tb): 17175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen return '__unittest' in tb.tb_frame.f_globals 17275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 17375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def _count_relevant_tb_levels(self, tb): 17475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen length = 0 17575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen while tb and not self._is_relevant_tb_level(tb): 17675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen length += 1 17775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen tb = tb.tb_next 17875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen return length 17975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen 18075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen def __repr__(self): 18175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen return "<%s run=%i errors=%i failures=%i>" % \ 18275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen (util.strclass(self.__class__), self.testsRun, len(self.errors), 18375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen len(self.failures)) 184