| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  | """Running tests""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import time | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from . import result | 
					
						
							| 
									
										
										
										
											2010-03-26 03:18:31 +00:00
										 |  |  | from .signals import registerResult | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-22 00:06:30 +00:00
										 |  |  | __unittest = True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class _WritelnDecorator(object): | 
					
						
							|  |  |  |     """Used to decorate file-like objects with a handy 'writeln' method""" | 
					
						
							|  |  |  |     def __init__(self,stream): | 
					
						
							|  |  |  |         self.stream = stream | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __getattr__(self, attr): | 
					
						
							| 
									
										
										
										
											2009-11-10 21:39:25 +00:00
										 |  |  |         if attr in ('stream', '__getstate__'): | 
					
						
							| 
									
										
										
										
											2009-11-10 20:49:30 +00:00
										 |  |  |             raise AttributeError(attr) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         return getattr(self.stream,attr) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def writeln(self, arg=None): | 
					
						
							|  |  |  |         if arg: | 
					
						
							|  |  |  |             self.write(arg) | 
					
						
							|  |  |  |         self.write('\n') # text-mode streams translate to \r\n if needed | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  | class TextTestResult(result.TestResult): | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |     """A test result class that can print formatted text results to a stream.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Used by TextTestRunner. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     separator1 = '=' * 70 | 
					
						
							|  |  |  |     separator2 = '-' * 70 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, stream, descriptions, verbosity): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         super(TextTestResult, self).__init__() | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         self.stream = stream | 
					
						
							|  |  |  |         self.showAll = verbosity > 1 | 
					
						
							|  |  |  |         self.dots = verbosity == 1 | 
					
						
							|  |  |  |         self.descriptions = descriptions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def getDescription(self, test): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         doc_first_line = test.shortDescription() | 
					
						
							|  |  |  |         if self.descriptions and doc_first_line: | 
					
						
							|  |  |  |             return '\n'.join((str(test), doc_first_line)) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             return str(test) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def startTest(self, test): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         super(TextTestResult, self).startTest(test) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         if self.showAll: | 
					
						
							|  |  |  |             self.stream.write(self.getDescription(test)) | 
					
						
							|  |  |  |             self.stream.write(" ... ") | 
					
						
							|  |  |  |             self.stream.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def addSuccess(self, test): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         super(TextTestResult, self).addSuccess(test) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         if self.showAll: | 
					
						
							|  |  |  |             self.stream.writeln("ok") | 
					
						
							|  |  |  |         elif self.dots: | 
					
						
							|  |  |  |             self.stream.write('.') | 
					
						
							|  |  |  |             self.stream.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def addError(self, test, err): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         super(TextTestResult, self).addError(test, err) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         if self.showAll: | 
					
						
							|  |  |  |             self.stream.writeln("ERROR") | 
					
						
							|  |  |  |         elif self.dots: | 
					
						
							|  |  |  |             self.stream.write('E') | 
					
						
							|  |  |  |             self.stream.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def addFailure(self, test, err): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         super(TextTestResult, self).addFailure(test, err) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         if self.showAll: | 
					
						
							|  |  |  |             self.stream.writeln("FAIL") | 
					
						
							|  |  |  |         elif self.dots: | 
					
						
							|  |  |  |             self.stream.write('F') | 
					
						
							|  |  |  |             self.stream.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def addSkip(self, test, reason): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         super(TextTestResult, self).addSkip(test, reason) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         if self.showAll: | 
					
						
							|  |  |  |             self.stream.writeln("skipped {0!r}".format(reason)) | 
					
						
							|  |  |  |         elif self.dots: | 
					
						
							|  |  |  |             self.stream.write("s") | 
					
						
							|  |  |  |             self.stream.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def addExpectedFailure(self, test, err): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         super(TextTestResult, self).addExpectedFailure(test, err) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         if self.showAll: | 
					
						
							|  |  |  |             self.stream.writeln("expected failure") | 
					
						
							|  |  |  |         elif self.dots: | 
					
						
							|  |  |  |             self.stream.write("x") | 
					
						
							|  |  |  |             self.stream.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def addUnexpectedSuccess(self, test): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         super(TextTestResult, self).addUnexpectedSuccess(test) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         if self.showAll: | 
					
						
							|  |  |  |             self.stream.writeln("unexpected success") | 
					
						
							|  |  |  |         elif self.dots: | 
					
						
							|  |  |  |             self.stream.write("u") | 
					
						
							|  |  |  |             self.stream.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def printErrors(self): | 
					
						
							|  |  |  |         if self.dots or self.showAll: | 
					
						
							|  |  |  |             self.stream.writeln() | 
					
						
							|  |  |  |         self.printErrorList('ERROR', self.errors) | 
					
						
							|  |  |  |         self.printErrorList('FAIL', self.failures) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def printErrorList(self, flavour, errors): | 
					
						
							|  |  |  |         for test, err in errors: | 
					
						
							|  |  |  |             self.stream.writeln(self.separator1) | 
					
						
							|  |  |  |             self.stream.writeln("%s: %s" % (flavour,self.getDescription(test))) | 
					
						
							|  |  |  |             self.stream.writeln(self.separator2) | 
					
						
							|  |  |  |             self.stream.writeln("%s" % err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TextTestRunner(object): | 
					
						
							|  |  |  |     """A test runner class that displays results in textual form.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     It prints out the names of tests as they are run, errors as they | 
					
						
							|  |  |  |     occur, and a summary of the results at the end of the test run. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |     resultclass = TextTestResult | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, | 
					
						
							| 
									
										
										
										
											2010-04-02 21:42:47 +00:00
										 |  |  |                  failfast=False, buffer=False, resultclass=None): | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         self.stream = _WritelnDecorator(stream) | 
					
						
							|  |  |  |         self.descriptions = descriptions | 
					
						
							|  |  |  |         self.verbosity = verbosity | 
					
						
							| 
									
										
										
										
											2010-03-22 01:01:34 +00:00
										 |  |  |         self.failfast = failfast | 
					
						
							| 
									
										
										
										
											2010-04-02 21:42:47 +00:00
										 |  |  |         self.buffer = buffer | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         if resultclass is not None: | 
					
						
							|  |  |  |             self.resultclass = resultclass | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _makeResult(self): | 
					
						
							| 
									
										
										
										
											2010-02-10 14:25:12 +00:00
										 |  |  |         return self.resultclass(self.stream, self.descriptions, self.verbosity) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def run(self, test): | 
					
						
							|  |  |  |         "Run the given test case or test suite." | 
					
						
							|  |  |  |         result = self._makeResult() | 
					
						
							| 
									
										
										
										
											2010-03-26 03:18:31 +00:00
										 |  |  |         registerResult(result) | 
					
						
							| 
									
										
										
										
											2010-03-22 01:01:34 +00:00
										 |  |  |         result.failfast = self.failfast | 
					
						
							| 
									
										
										
										
											2010-04-02 21:42:47 +00:00
										 |  |  |         result.buffer = self.buffer | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         startTime = time.time() | 
					
						
							|  |  |  |         startTestRun = getattr(result, 'startTestRun', None) | 
					
						
							|  |  |  |         if startTestRun is not None: | 
					
						
							|  |  |  |             startTestRun() | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             test(result) | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             stopTestRun = getattr(result, 'stopTestRun', None) | 
					
						
							|  |  |  |             if stopTestRun is not None: | 
					
						
							|  |  |  |                 stopTestRun() | 
					
						
							|  |  |  |         stopTime = time.time() | 
					
						
							|  |  |  |         timeTaken = stopTime - startTime | 
					
						
							|  |  |  |         result.printErrors() | 
					
						
							| 
									
										
										
										
											2010-02-23 17:00:53 +00:00
										 |  |  |         if hasattr(result, 'separator2'): | 
					
						
							|  |  |  |             self.stream.writeln(result.separator2) | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         run = result.testsRun | 
					
						
							|  |  |  |         self.stream.writeln("Ran %d test%s in %.3fs" % | 
					
						
							|  |  |  |                             (run, run != 1 and "s" or "", timeTaken)) | 
					
						
							|  |  |  |         self.stream.writeln() | 
					
						
							| 
									
										
										
										
											2010-02-23 17:00:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expectedFails = unexpectedSuccesses = skipped = 0 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             results = map(len, (result.expectedFailures, | 
					
						
							|  |  |  |                                 result.unexpectedSuccesses, | 
					
						
							|  |  |  |                                 result.skipped)) | 
					
						
							|  |  |  |             expectedFails, unexpectedSuccesses, skipped = results | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-19 20:18:21 +00:00
										 |  |  |         infos = [] | 
					
						
							|  |  |  |         if not result.wasSuccessful(): | 
					
						
							|  |  |  |             self.stream.write("FAILED") | 
					
						
							|  |  |  |             failed, errored = map(len, (result.failures, result.errors)) | 
					
						
							|  |  |  |             if failed: | 
					
						
							|  |  |  |                 infos.append("failures=%d" % failed) | 
					
						
							|  |  |  |             if errored: | 
					
						
							|  |  |  |                 infos.append("errors=%d" % errored) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.stream.write("OK") | 
					
						
							|  |  |  |         if skipped: | 
					
						
							|  |  |  |             infos.append("skipped=%d" % skipped) | 
					
						
							|  |  |  |         if expectedFails: | 
					
						
							|  |  |  |             infos.append("expected failures=%d" % expectedFails) | 
					
						
							|  |  |  |         if unexpectedSuccesses: | 
					
						
							|  |  |  |             infos.append("unexpected successes=%d" % unexpectedSuccesses) | 
					
						
							|  |  |  |         if infos: | 
					
						
							|  |  |  |             self.stream.writeln(" (%s)" % (", ".join(infos),)) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.stream.write("\n") | 
					
						
							|  |  |  |         return result |