1# Copyright (c) 2009-2010 testtools developers. See LICENSE for details. 2 3"""Doubles of test result objects, useful for testing unittest code.""" 4 5__all__ = [ 6 'Python26TestResult', 7 'Python27TestResult', 8 'ExtendedTestResult', 9 'StreamResult', 10 ] 11 12 13from testtools.tags import TagContext 14 15 16class LoggingBase(object): 17 """Basic support for logging of results.""" 18 19 def __init__(self): 20 self._events = [] 21 self.shouldStop = False 22 self._was_successful = True 23 self.testsRun = 0 24 25 26class Python26TestResult(LoggingBase): 27 """A precisely python 2.6 like test result, that logs.""" 28 29 def addError(self, test, err): 30 self._was_successful = False 31 self._events.append(('addError', test, err)) 32 33 def addFailure(self, test, err): 34 self._was_successful = False 35 self._events.append(('addFailure', test, err)) 36 37 def addSuccess(self, test): 38 self._events.append(('addSuccess', test)) 39 40 def startTest(self, test): 41 self._events.append(('startTest', test)) 42 self.testsRun += 1 43 44 def stop(self): 45 self.shouldStop = True 46 47 def stopTest(self, test): 48 self._events.append(('stopTest', test)) 49 50 def wasSuccessful(self): 51 return self._was_successful 52 53 54class Python27TestResult(Python26TestResult): 55 """A precisely python 2.7 like test result, that logs.""" 56 57 def __init__(self): 58 super(Python27TestResult, self).__init__() 59 self.failfast = False 60 61 def addError(self, test, err): 62 super(Python27TestResult, self).addError(test, err) 63 if self.failfast: 64 self.stop() 65 66 def addFailure(self, test, err): 67 super(Python27TestResult, self).addFailure(test, err) 68 if self.failfast: 69 self.stop() 70 71 def addExpectedFailure(self, test, err): 72 self._events.append(('addExpectedFailure', test, err)) 73 74 def addSkip(self, test, reason): 75 self._events.append(('addSkip', test, reason)) 76 77 def addUnexpectedSuccess(self, test): 78 self._events.append(('addUnexpectedSuccess', test)) 79 if self.failfast: 80 self.stop() 81 82 def startTestRun(self): 83 self._events.append(('startTestRun',)) 84 85 def stopTestRun(self): 86 self._events.append(('stopTestRun',)) 87 88 89class ExtendedTestResult(Python27TestResult): 90 """A test result like the proposed extended unittest result API.""" 91 92 def __init__(self): 93 super(ExtendedTestResult, self).__init__() 94 self._tags = TagContext() 95 96 def addError(self, test, err=None, details=None): 97 self._was_successful = False 98 self._events.append(('addError', test, err or details)) 99 100 def addFailure(self, test, err=None, details=None): 101 self._was_successful = False 102 self._events.append(('addFailure', test, err or details)) 103 104 def addExpectedFailure(self, test, err=None, details=None): 105 self._events.append(('addExpectedFailure', test, err or details)) 106 107 def addSkip(self, test, reason=None, details=None): 108 self._events.append(('addSkip', test, reason or details)) 109 110 def addSuccess(self, test, details=None): 111 if details: 112 self._events.append(('addSuccess', test, details)) 113 else: 114 self._events.append(('addSuccess', test)) 115 116 def addUnexpectedSuccess(self, test, details=None): 117 self._was_successful = False 118 if details is not None: 119 self._events.append(('addUnexpectedSuccess', test, details)) 120 else: 121 self._events.append(('addUnexpectedSuccess', test)) 122 123 def progress(self, offset, whence): 124 self._events.append(('progress', offset, whence)) 125 126 def startTestRun(self): 127 super(ExtendedTestResult, self).startTestRun() 128 self._was_successful = True 129 self._tags = TagContext() 130 131 def startTest(self, test): 132 super(ExtendedTestResult, self).startTest(test) 133 self._tags = TagContext(self._tags) 134 135 def stopTest(self, test): 136 self._tags = self._tags.parent 137 super(ExtendedTestResult, self).stopTest(test) 138 139 @property 140 def current_tags(self): 141 return self._tags.get_current_tags() 142 143 def tags(self, new_tags, gone_tags): 144 self._tags.change_tags(new_tags, gone_tags) 145 self._events.append(('tags', new_tags, gone_tags)) 146 147 def time(self, time): 148 self._events.append(('time', time)) 149 150 def wasSuccessful(self): 151 return self._was_successful 152 153 154class StreamResult(object): 155 """A StreamResult implementation for testing. 156 157 All events are logged to _events. 158 """ 159 160 def __init__(self): 161 self._events = [] 162 163 def startTestRun(self): 164 self._events.append(('startTestRun',)) 165 166 def stopTestRun(self): 167 self._events.append(('stopTestRun',)) 168 169 def status(self, test_id=None, test_status=None, test_tags=None, 170 runnable=True, file_name=None, file_bytes=None, eof=False, 171 mime_type=None, route_code=None, timestamp=None): 172 self._events.append(('status', test_id, test_status, test_tags, 173 runnable, file_name, file_bytes, eof, mime_type, route_code, 174 timestamp)) 175