1 """Unittest main program"""
7 from django
.utils
.unittest
import loader
, runner
9 from django
.utils
.unittest
.signals
import installHandler
15 FAILFAST
= " -f, --failfast Stop on first failure\n"
16 CATCHBREAK
= " -c, --catch Catch control-C and display results\n"
17 BUFFEROUTPUT
= " -b, --buffer Buffer stdout and stderr during test runs\n"
20 Usage: %(progName)s [options] [tests]
23 -h, --help Show this message
24 -v, --verbose Verbose output
25 -q, --quiet Minimal output
26 %(failfast)s%(catchbreak)s%(buffer)s
28 %(progName)s test_module - run tests from test_module
29 %(progName)s test_module.TestClass - run tests from
31 %(progName)s test_module.TestClass.test_method - run specified test method
33 [tests] can be a list of any number of test modules, classes and test
36 Alternative Usage: %(progName)s discover [options]
39 -v, --verbose Verbose output
40 %(failfast)s%(catchbreak)s%(buffer)s -s directory Directory to start discovery ('.' default)
41 -p pattern Pattern to match test files ('test*.py' default)
42 -t directory Top level directory of project (default to
45 For test discovery all test modules must be importable from the top
46 level directory of the project.
49 USAGE_FROM_MODULE
= """\
50 Usage: %(progName)s [options] [test] [...]
53 -h, --help Show this message
54 -v, --verbose Verbose output
55 -q, --quiet Minimal output
56 %(failfast)s%(catchbreak)s%(buffer)s
58 %(progName)s - run default set of tests
59 %(progName)s MyTestSuite - run suite 'MyTestSuite'
60 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
61 %(progName)s MyTestCase - run all 'test*' test methods
66 class TestProgram(object):
67 """A command-line program that runs a set of tests; this is primarily
68 for making test modules conveniently executable.
70 USAGE
= USAGE_FROM_MODULE
72 # defaults for testing
73 failfast
= catchbreak
= buffer = progName
= None
75 def __init__(self
, module
='__main__', defaultTest
=None,
76 argv
=None, testRunner
=None,
77 testLoader
=loader
.defaultTestLoader
, exit
=True,
78 verbosity
=1, failfast
=None, catchbreak
=None, buffer=None):
79 if isinstance(module
, basestring
):
80 self
.module
= __import__(module
)
81 for part
in module
.split('.')[1:]:
82 self
.module
= getattr(self
.module
, part
)
89 self
.verbosity
= verbosity
90 self
.failfast
= failfast
91 self
.catchbreak
= catchbreak
93 self
.defaultTest
= defaultTest
94 self
.testRunner
= testRunner
95 self
.testLoader
= testLoader
96 self
.progName
= os
.path
.basename(argv
[0])
100 def usageExit(self
, msg
=None):
103 usage
= {'progName': self
.progName
, 'catchbreak': '', 'failfast': '',
105 if self
.failfast
!= False:
106 usage
['failfast'] = FAILFAST
107 if self
.catchbreak
!= False and installHandler
is not None:
108 usage
['catchbreak'] = CATCHBREAK
109 if self
.buffer != False:
110 usage
['buffer'] = BUFFEROUTPUT
111 print self
.USAGE
% usage
114 def parseArgs(self
, argv
):
115 if len(argv
) > 1 and argv
[1].lower() == 'discover':
116 self
._do
_discovery
(argv
[2:])
120 long_opts
= ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer']
122 options
, args
= getopt
.getopt(argv
[1:], 'hHvqfcb', long_opts
)
123 for opt
, value
in options
:
124 if opt
in ('-h','-H','--help'):
126 if opt
in ('-q','--quiet'):
128 if opt
in ('-v','--verbose'):
130 if opt
in ('-f','--failfast'):
131 if self
.failfast
is None:
133 # Should this raise an exception if -f is not valid?
134 if opt
in ('-c','--catch'):
135 if self
.catchbreak
is None and installHandler
is not None:
136 self
.catchbreak
= True
137 # Should this raise an exception if -c is not valid?
138 if opt
in ('-b','--buffer'):
139 if self
.buffer is None:
141 # Should this raise an exception if -b is not valid?
142 if len(args
) == 0 and self
.defaultTest
is None:
143 # createTests will load tests from self.module
144 self
.testNames
= None
146 self
.testNames
= args
147 if __name__
== '__main__':
148 # to support python -m unittest ...
151 self
.testNames
= (self
.defaultTest
,)
153 except getopt
.error
, msg
:
156 def createTests(self
):
157 if self
.testNames
is None:
158 self
.test
= self
.testLoader
.loadTestsFromModule(self
.module
)
160 self
.test
= self
.testLoader
.loadTestsFromNames(self
.testNames
,
163 def _do_discovery(self
, argv
, Loader
=loader
.TestLoader
):
164 # handle command line args for test discovery
165 self
.progName
= '%s discover' % self
.progName
167 parser
= optparse
.OptionParser()
168 parser
.prog
= self
.progName
169 parser
.add_option('-v', '--verbose', dest
='verbose', default
=False,
170 help='Verbose output', action
='store_true')
171 if self
.failfast
!= False:
172 parser
.add_option('-f', '--failfast', dest
='failfast', default
=False,
173 help='Stop on first fail or error',
175 if self
.catchbreak
!= False and installHandler
is not None:
176 parser
.add_option('-c', '--catch', dest
='catchbreak', default
=False,
177 help='Catch ctrl-C and display results so far',
179 if self
.buffer != False:
180 parser
.add_option('-b', '--buffer', dest
='buffer', default
=False,
181 help='Buffer stdout and stderr during tests',
183 parser
.add_option('-s', '--start-directory', dest
='start', default
='.',
184 help="Directory to start discovery ('.' default)")
185 parser
.add_option('-p', '--pattern', dest
='pattern', default
='test*.py',
186 help="Pattern to match tests ('test*.py' default)")
187 parser
.add_option('-t', '--top-level-directory', dest
='top', default
=None,
188 help='Top level directory of project (defaults to start directory)')
190 options
, args
= parser
.parse_args(argv
)
194 for name
, value
in zip(('start', 'pattern', 'top'), args
):
195 setattr(options
, name
, value
)
197 # only set options from the parsing here
198 # if they weren't set explicitly in the constructor
199 if self
.failfast
is None:
200 self
.failfast
= options
.failfast
201 if self
.catchbreak
is None and installHandler
is not None:
202 self
.catchbreak
= options
.catchbreak
203 if self
.buffer is None:
204 self
.buffer = options
.buffer
209 start_dir
= options
.start
210 pattern
= options
.pattern
211 top_level_dir
= options
.top
214 self
.test
= loader
.discover(start_dir
, pattern
, top_level_dir
)
219 if self
.testRunner
is None:
220 self
.testRunner
= runner
.TextTestRunner
221 if isinstance(self
.testRunner
, (type, types
.ClassType
)):
223 testRunner
= self
.testRunner(verbosity
=self
.verbosity
,
224 failfast
=self
.failfast
,
227 # didn't accept the verbosity, buffer or failfast arguments
228 testRunner
= self
.testRunner()
230 # it is assumed to be a TestRunner instance
231 testRunner
= self
.testRunner
232 self
.result
= testRunner
.run(self
.test
)
234 sys
.exit(not self
.result
.wasSuccessful())
239 TestProgram
.USAGE
= USAGE_AS_MAIN