1 """Unittest main program"""
7 from . import loader
, runner
11 Usage: %(progName)s [options] [tests]
14 -h, --help Show this message
15 -v, --verbose Verbose output
16 -q, --quiet Minimal output
19 %(progName)s test_module - run tests from test_module
20 %(progName)s test_module.TestClass - run tests from
22 %(progName)s test_module.TestClass.test_method - run specified test method
24 [tests] can be a list of any number of test modules, classes and test
27 Alternative Usage: %(progName)s discover [options]
30 -v, --verbose Verbose output
31 -s directory Directory to start discovery ('.' default)
32 -p pattern Pattern to match test files ('test*.py' default)
33 -t directory Top level directory of project (default to
36 For test discovery all test modules must be importable from the top
37 level directory of the project.
40 USAGE_FROM_MODULE
= """\
41 Usage: %(progName)s [options] [test] [...]
44 -h, --help Show this message
45 -v, --verbose Verbose output
46 -q, --quiet Minimal output
49 %(progName)s - run default set of tests
50 %(progName)s MyTestSuite - run suite 'MyTestSuite'
51 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
52 %(progName)s MyTestCase - run all 'test*' test methods
56 if __name__
== '__main__':
59 USAGE
= USAGE_FROM_MODULE
62 class TestProgram(object):
63 """A command-line program that runs a set of tests; this is primarily
64 for making test modules conveniently executable.
67 def __init__(self
, module
='__main__', defaultTest
=None,
68 argv
=None, testRunner
=None,
69 testLoader
=loader
.defaultTestLoader
, exit
=True,
71 if isinstance(module
, basestring
):
72 self
.module
= __import__(module
)
73 for part
in module
.split('.')[1:]:
74 self
.module
= getattr(self
.module
, part
)
81 self
.verbosity
= verbosity
82 self
.defaultTest
= defaultTest
83 self
.testRunner
= testRunner
84 self
.testLoader
= testLoader
85 self
.progName
= os
.path
.basename(argv
[0])
89 def usageExit(self
, msg
=None):
92 print self
.USAGE
% self
.__dict
__
95 def parseArgs(self
, argv
):
96 if len(argv
) > 1 and argv
[1].lower() == 'discover':
97 self
._do
_discovery
(argv
[2:])
101 long_opts
= ['help','verbose','quiet']
103 options
, args
= getopt
.getopt(argv
[1:], 'hHvq', long_opts
)
104 for opt
, value
in options
:
105 if opt
in ('-h','-H','--help'):
107 if opt
in ('-q','--quiet'):
109 if opt
in ('-v','--verbose'):
111 if len(args
) == 0 and self
.defaultTest
is None:
112 # createTests will load tests from self.module
113 self
.testNames
= None
115 self
.testNames
= args
116 if __name__
== '__main__':
117 # to support python -m unittest ...
120 self
.testNames
= (self
.defaultTest
,)
122 except getopt
.error
, msg
:
125 def createTests(self
):
126 if self
.testNames
is None:
127 self
.test
= self
.testLoader
.loadTestsFromModule(self
.module
)
129 self
.test
= self
.testLoader
.loadTestsFromNames(self
.testNames
,
132 def _do_discovery(self
, argv
, Loader
=loader
.TestLoader
):
133 # handle command line args for test discovery
135 parser
= optparse
.OptionParser()
136 parser
.add_option('-v', '--verbose', dest
='verbose', default
=False,
137 help='Verbose output', action
='store_true')
138 parser
.add_option('-s', '--start-directory', dest
='start', default
='.',
139 help="Directory to start discovery ('.' default)")
140 parser
.add_option('-p', '--pattern', dest
='pattern', default
='test*.py',
141 help="Pattern to match tests ('test*.py' default)")
142 parser
.add_option('-t', '--top-level-directory', dest
='top', default
=None,
143 help='Top level directory of project (defaults to start directory)')
145 options
, args
= parser
.parse_args(argv
)
149 for name
, value
in zip(('start', 'pattern', 'top'), args
):
150 setattr(options
, name
, value
)
155 start_dir
= options
.start
156 pattern
= options
.pattern
157 top_level_dir
= options
.top
160 self
.test
= loader
.discover(start_dir
, pattern
, top_level_dir
)
163 if self
.testRunner
is None:
164 self
.testRunner
= runner
.TextTestRunner
165 if isinstance(self
.testRunner
, (type, types
.ClassType
)):
167 testRunner
= self
.testRunner(verbosity
=self
.verbosity
)
169 # didn't accept the verbosity argument
170 testRunner
= self
.testRunner()
172 # it is assumed to be a TestRunner instance
173 testRunner
= self
.testRunner
174 self
.result
= testRunner
.run(self
.test
)
176 sys
.exit(not self
.result
.wasSuccessful())