| # Copyright 2018 The Abseil Authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """TestResult implementing default output for test execution status.""" |
| |
| import unittest |
| |
| |
| class TextTestResult(unittest.TextTestResult): |
| """TestResult class that provides the default text result formatting.""" |
| |
| def __init__(self, stream, descriptions, verbosity): |
| # Disable the verbose per-test output from the superclass, since it would |
| # conflict with our customized output. |
| super(TextTestResult, self).__init__(stream, descriptions, 0) |
| self._per_test_output = verbosity > 0 |
| |
| def _print_status(self, tag, test): |
| if self._per_test_output: |
| test_id = test.id() |
| if test_id.startswith('__main__.'): |
| test_id = test_id[len('__main__.'):] |
| print('[%s] %s' % (tag, test_id), file=self.stream) |
| self.stream.flush() |
| |
| def startTest(self, test): |
| super(TextTestResult, self).startTest(test) |
| self._print_status(' RUN ', test) |
| |
| def addSuccess(self, test): |
| super(TextTestResult, self).addSuccess(test) |
| self._print_status(' OK ', test) |
| |
| def addError(self, test, err): |
| super(TextTestResult, self).addError(test, err) |
| self._print_status(' FAILED ', test) |
| |
| def addFailure(self, test, err): |
| super(TextTestResult, self).addFailure(test, err) |
| self._print_status(' FAILED ', test) |
| |
| def addSkip(self, test, reason): |
| super(TextTestResult, self).addSkip(test, reason) |
| self._print_status(' SKIPPED ', test) |
| |
| def addExpectedFailure(self, test, err): |
| super(TextTestResult, self).addExpectedFailure(test, err) |
| self._print_status(' OK ', test) |
| |
| def addUnexpectedSuccess(self, test): |
| super(TextTestResult, self).addUnexpectedSuccess(test) |
| self._print_status(' FAILED ', test) |
| |
| |
| class TextTestRunner(unittest.TextTestRunner): |
| """A test runner that produces formatted text results.""" |
| |
| _TEST_RESULT_CLASS = TextTestResult |
| |
| # Set this to true at the class or instance level to run tests using a |
| # debug-friendly method (e.g, one that doesn't catch exceptions and interacts |
| # better with debuggers). |
| # Usually this is set using --pdb_post_mortem. |
| run_for_debugging = False |
| |
| def run(self, test): |
| # type: (TestCase) -> TestResult |
| if self.run_for_debugging: |
| return self._run_debug(test) |
| else: |
| return super(TextTestRunner, self).run(test) |
| |
| def _run_debug(self, test): |
| # type: (TestCase) -> TestResult |
| test.debug() |
| # Return an empty result to indicate success. |
| return self._makeResult() |
| |
| def _makeResult(self): |
| return TextTestResult(self.stream, self.descriptions, self.verbosity) |