summaryrefslogtreecommitdiff
path: root/testing/framework/TestUnit/taprunner.py
blob: 01e0e813ac341a724856fbe35619ad6eca4c17cb (plain)
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
"""
Format unittest results in Test Anything Protocol (TAP).
http://testanything.org/tap-version-13-specification.html

Public domain work by:
  anatoly techtonik <techtonik@gmail.com>

"""

from unittest import suite
from unittest.runner import TextTestRunner, TextTestResult

__version__ = "0.1"

class TAPTestResult(TextTestResult):

    def _process(self, test, msg, failtype = None, directive = None):
        """ increase the counter, format and output TAP info """
        # counterhack: increase test counter
        test.suite.tap_counter += 1
        msg = "%s %d" % (msg, test.suite.tap_counter)
        if "not" not in msg:
            msg += "    "  # justify
        self.stream.write("%s - " % msg)
        if failtype:
            self.stream.write("%s - " % failtype)
        self.stream.write("%s" % test.__class__.__name__)
        self.stream.write(".%s" % test._testMethodName)
        if directive:
            self.stream.write(directive)
        self.stream.write("\n")
        # [ ] write test __doc__ (if exists) in comment
        self.stream.flush()

    def addSuccess(self, test):
        super(TextTestResult, self).addSuccess(test)
        self._process(test, "ok")

    def addFailure(self, test, err):
        super(TextTestResult, self).addFailure(test, err)
        self._process(test, "not ok", "FAIL")
        # [ ] add structured data about assertion

    def addError(self, test, err):
        super(TextTestResult, self).addError(test, err)
        self._process(test, "not ok", "ERROR")
        # [ ] add structured data about exception

    def addSkip(self, test, reason):
        super(TextTestResult, self).addSkip(test, reason)
        self._process(test, "ok", directive=("  # SKIP  %s" % reason))

    def addExpectedFailure(self, test, err):
        super(TextTestResult, self).addExpectedFailure(test, err)
        self._process(test, "not ok", directive=("  # TODO"))

    def addUnexpectedSuccess(self, test):
        super(TextTestResult, self).addUnexpectedSuccess(test)
        self._process(test, "not ok", "FAIL (unexpected success)")

    """
    def printErrors(self):
    def printErrorList(self, flavour, errors):
    """


class TAPTestRunner(TextTestRunner):
    resultclass = TAPTestResult

    def run(self, test):
        self.stream.write("TAP version 13\n")
        # [ ] add commented block with test suite __doc__
        # [ ] check call with a single test
        # if isinstance(test, suite.TestSuite):
        self.stream.write("1..%s\n" % len(list(test)))

        # counterhack: inject test counter into test suite
        test.tap_counter = 0
        # counterhack: inject reference to suite into each test case
        for case in test:
            case.suite = test

        return super(TAPTestRunner, self).run(test)


if __name__ == "__main__":
    import sys
    import unittest

    class Test(unittest.TestCase):
       def test_ok(self):
           pass
       def test_fail(self):
           self.assertTrue(False)
       def test_error(self):
           bad_symbol
       @unittest.skip("skipin'")
       def test_skip(self):
           pass
       @unittest.expectedFailure
       def test_not_ready(self):
           self.fail()
       @unittest.expectedFailure
       def test_invalid_fail_mark(self):
           pass
       def test_another_ok(self):
           pass


    suite = unittest.TestSuite([
       Test('test_ok'),
       Test('test_fail'),
       Test('test_error'),
       Test('test_skip'),
       Test('test_not_ready'),
       Test('test_invalid_fail_mark'),
       Test('test_another_ok')
    ])
    if not TAPTestRunner().run(suite).wasSuccessful():
       sys.exit(1)