1# Copyright 2018 The Abseil Authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""TestResult implementing default output for test execution status.""" 16 17import unittest 18 19 20class TextTestResult(unittest.TextTestResult): 21 """TestResult class that provides the default text result formatting.""" 22 23 def __init__(self, stream, descriptions, verbosity): 24 # Disable the verbose per-test output from the superclass, since it would 25 # conflict with our customized output. 26 super(TextTestResult, self).__init__(stream, descriptions, 0) 27 self._per_test_output = verbosity > 0 28 29 def _print_status(self, tag, test): 30 if self._per_test_output: 31 test_id = test.id() 32 if test_id.startswith('__main__.'): 33 test_id = test_id[len('__main__.'):] 34 print('[%s] %s' % (tag, test_id), file=self.stream) 35 self.stream.flush() 36 37 def startTest(self, test): 38 super(TextTestResult, self).startTest(test) 39 self._print_status(' RUN ', test) 40 41 def addSuccess(self, test): 42 super(TextTestResult, self).addSuccess(test) 43 self._print_status(' OK ', test) 44 45 def addError(self, test, err): 46 super(TextTestResult, self).addError(test, err) 47 self._print_status(' FAILED ', test) 48 49 def addFailure(self, test, err): 50 super(TextTestResult, self).addFailure(test, err) 51 self._print_status(' FAILED ', test) 52 53 def addSkip(self, test, reason): 54 super(TextTestResult, self).addSkip(test, reason) 55 self._print_status(' SKIPPED ', test) 56 57 def addExpectedFailure(self, test, err): 58 super(TextTestResult, self).addExpectedFailure(test, err) 59 self._print_status(' OK ', test) 60 61 def addUnexpectedSuccess(self, test): 62 super(TextTestResult, self).addUnexpectedSuccess(test) 63 self._print_status(' FAILED ', test) 64 65 66class TextTestRunner(unittest.TextTestRunner): 67 """A test runner that produces formatted text results.""" 68 69 _TEST_RESULT_CLASS = TextTestResult 70 71 # Set this to true at the class or instance level to run tests using a 72 # debug-friendly method (e.g, one that doesn't catch exceptions and interacts 73 # better with debuggers). 74 # Usually this is set using --pdb_post_mortem. 75 run_for_debugging = False 76 77 def run(self, test): 78 # type: (TestCase) -> TestResult 79 if self.run_for_debugging: 80 return self._run_debug(test) 81 else: 82 return super(TextTestRunner, self).run(test) 83 84 def _run_debug(self, test): 85 # type: (TestCase) -> TestResult 86 test.debug() 87 # Return an empty result to indicate success. 88 return self._makeResult() 89 90 def _makeResult(self): 91 return TextTestResult(self.stream, self.descriptions, self.verbosity) 92