/usr/lib/python3/dist-packages/tap/runner.py is in python3-tap 2.2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | # Copyright (c) 2018, Matt Layman and contributors
import os
from unittest import TextTestResult, TextTestRunner
from unittest.runner import _WritelnDecorator
import sys
from tap import formatter
from tap.i18n import _
from tap.tracker import Tracker
class TAPTestResult(TextTestResult):
FORMAT = None
def __init__(self, stream, descriptions, verbosity):
super(TAPTestResult, self).__init__(stream, descriptions, verbosity)
def stopTestRun(self):
"""Once the test run is complete, generate each of the TAP files."""
super(TAPTestResult, self).stopTestRun()
self.tracker.generate_tap_reports()
def addError(self, test, err):
super(TAPTestResult, self).addError(test, err)
diagnostics = formatter.format_exception(err)
self.tracker.add_not_ok(
self._cls_name(test), self._description(test),
diagnostics=diagnostics)
def addFailure(self, test, err):
super(TAPTestResult, self).addFailure(test, err)
diagnostics = formatter.format_exception(err)
self.tracker.add_not_ok(
self._cls_name(test), self._description(test),
diagnostics=diagnostics)
def addSuccess(self, test):
super(TAPTestResult, self).addSuccess(test)
self.tracker.add_ok(self._cls_name(test), self._description(test))
def addSkip(self, test, reason):
super(TAPTestResult, self).addSkip(test, reason)
self.tracker.add_skip(
self._cls_name(test), self._description(test), reason)
def addExpectedFailure(self, test, err):
super(TAPTestResult, self).addExpectedFailure(test, err)
diagnostics = formatter.format_exception(err)
self.tracker.add_not_ok(
self._cls_name(test), self._description(test),
_('(expected failure)'), diagnostics=diagnostics)
def addUnexpectedSuccess(self, test):
super(TAPTestResult, self).addUnexpectedSuccess(test)
self.tracker.add_ok(self._cls_name(test), self._description(test),
_('(unexpected success)'))
def _cls_name(self, test):
return test.__class__.__name__
def _description(self, test):
if self.FORMAT:
try:
return self.FORMAT.format(
method_name=str(test),
short_description=test.shortDescription() or '')
except KeyError:
sys.exit(_(
'Bad format string: {format}\n'
'Replacement options are: {{short_description}} and '
'{{method_name}}').format(format=self.FORMAT))
return test.shortDescription() or str(test)
# TODO: 2016-7-30 mblayman - Since the 2.6 signature is no longer relevant,
# check the possibility of removing the module level scope.
# Module level state stinks, but this is the only way to keep compatibility
# with Python 2.6. The best place for the tracker is as an instance variable
# on the runner, but __init__ is so different that it is not easy to create
# a runner that satisfies every supported Python version.
_tracker = Tracker()
class TAPTestRunner(TextTestRunner):
"""A test runner that will behave exactly like TextTestRunner and will
additionally generate TAP files for each test case"""
resultclass = TAPTestResult
def set_stream(self, streaming):
"""Set the streaming boolean option to stream TAP directly to stdout.
The test runner default output will be suppressed in favor of TAP.
"""
self.stream = _WritelnDecorator(open(os.devnull, 'w'))
_tracker.streaming = streaming
_tracker.stream = sys.stdout
def _makeResult(self):
result = self.resultclass(
self.stream, self.descriptions, self.verbosity)
result.tracker = _tracker
return result
@classmethod
def set_outdir(cls, outdir):
"""Set the output directory so that TAP files are written to the
specified outdir location.
"""
# Blame the lack of unittest extensibility for this hacky method.
_tracker.outdir = outdir
@classmethod
def set_combined(cls, combined):
"""Set the tracker to use a single output file."""
_tracker.combined = combined
@classmethod
def set_header(cls, header):
"""Set the header display flag."""
_tracker.header = header
@classmethod
def set_format(cls, fmt):
"""Set the format of each test line.
The format string can use:
* {method_name}: The test method name
* {short_description}: The test's docstring short description
"""
TAPTestResult.FORMAT = fmt
|