addTest now mirrors unittest api
[third_party/subunit] / test_all.py
1 #!/usr/bin/env python
2 # -*- Mode: python -*-
3 #
4 # Copyright (C) 2004 Canonical.com 
5 #       Author:      Robert Collins <robert.collins@canonical.com>
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 #
21
22 import unittest
23 import sys
24 import os
25 import shutil
26 import logging
27
28 class ParameterisableTextTestRunner(unittest.TextTestRunner):
29     """I am a TextTestRunner whose result class is 
30     parameterisable without further subclassing"""
31     def __init__(self, **args):
32         unittest.TextTestRunner.__init__(self, **args)
33         self._resultFactory=None
34     def resultFactory(self, *args):
35         """set or retrieve the result factory"""
36         if args:
37             self._resultFactory=args[0]
38             return self
39         if self._resultFactory is None:
40             self._resultFactory=unittest._TextTestResult
41         return self._resultFactory
42         
43     def _makeResult(self):
44         return self.resultFactory()(self.stream, self.descriptions, self.verbosity)
45
46
47 class EarlyStoppingTextTestResult(unittest._TextTestResult):
48     """I am a TextTestResult that can optionally stop at the first failure
49     or error"""
50
51     def addError(self, test, err):
52         unittest._TextTestResult.addError(self, test, err)
53         if self.stopOnError():
54             self.stop()
55
56     def addFailure(self, test, err):
57         unittest._TextTestResult.addError(self, test, err)
58         if self.stopOnFailure():
59             self.stop()
60
61     def stopOnError(self, *args):
62         """should this result indicate an abort when an error occurs?
63         TODO parameterise this"""
64         return True
65
66     def stopOnFailure(self, *args):
67         """should this result indicate an abort when a failure error occurs?
68         TODO parameterise this"""
69         return True
70
71
72 def earlyStopFactory(*args, **kwargs):
73     """return a an early stopping text test result"""
74     result=EarlyStoppingTextTestResult(*args, **kwargs)
75     return result
76
77 from subunit.tests.TestUtil import TestVisitor, TestSuite
78
79 def test_suite():
80     result = TestSuite()
81     import subunit
82     result.addTest(subunit.test_suite())
83     return result
84
85
86 class filteringVisitor(TestVisitor):
87     """I accruse all the testCases I visit that pass a regexp filter on id
88     into my suite
89     """
90
91     def __init__(self, filter):
92         import re
93         TestVisitor.__init__(self)
94         self._suite=None
95         self.filter=re.compile(filter)
96
97     def suite(self):
98         """answer the suite we are building"""
99         if self._suite is None:
100             self._suite=TestSuite()
101         return self._suite
102
103     def visitCase(self, aCase):
104         if self.filter.match(aCase.id()):
105             self.suite().addTest(aCase)
106
107
108 def main(argv):
109     """To parameterise what tests are run, run this script like so:
110     python test_all.py REGEX
111     i.e.
112     python test_all.py .*Protocol.*
113     to run all tests with Protocol in their id."""
114     if len(argv) > 1:
115         pattern = argv[1]
116     else:
117         pattern = ".*"
118     visitor = filteringVisitor(pattern)
119     test_suite().visit(visitor)
120     runner = ParameterisableTextTestRunner(verbosity=2)
121     runner.resultFactory(earlyStopFactory)
122     if not runner.run(visitor.suite()).wasSuccessful():
123         return 1
124     return 0
125
126 if __name__ == '__main__':
127     sys.exit(main(sys.argv))