2 # Copyright (c) 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
13 def FilterSuite(suite, predicate):
14 if hasattr(suite, 'recreateEmptyVersion'):
15 new_suite = suite.recreateEmptyVersion()
17 new_suite = suite.__class__()
20 if isinstance(x, unittest.TestSuite):
21 subsuite = FilterSuite(x, predicate)
22 if subsuite.countTestCases() == 0:
25 new_suite.addTest(subsuite)
28 assert isinstance(x, unittest.TestCase)
34 class _TestLoader(unittest.TestLoader):
35 def __init__(self, *args):
36 super(_TestLoader, self).__init__(*args)
37 self.discover_calls = []
39 def loadTestsFromModule(self, module, use_load_tests=True):
40 if module.__file__ != __file__:
41 return super(_TestLoader, self).loadTestsFromModule(module, use_load_tests)
43 suite = unittest.TestSuite()
44 for discover_args in self.discover_calls:
45 subsuite = self.discover(*discover_args)
46 suite.addTest(subsuite)
49 class _RunnerImpl(unittest.TextTestRunner):
50 def __init__(self, filters):
51 super(_RunnerImpl, self).__init__(verbosity=2)
52 self.filters = filters
54 def ShouldTestRun(self, test):
55 if len(self.filters) == 0:
58 for name in self.filters:
64 filtered_test = FilterSuite(suite, self.ShouldTestRun)
65 return super(_RunnerImpl, self).run(filtered_test)
70 class TestRunner(object):
72 self._loader = _TestLoader()
74 def AddModule(self, module, pattern="*unittest.py"):
75 assert inspect.ismodule(module)
76 module_file_basename = os.path.splitext(os.path.basename(module.__file__))[0]
77 if module_file_basename != '__init__':
78 raise NotImplementedError('Modules that are one file are not supported, only directories.')
80 file_basename = os.path.basename(os.path.dirname(module.__file__))
81 module_first_dir = module.__name__.split('.')[0]
82 assert file_basename == module_first_dir, 'Module must be toplevel'
84 start_dir = os.path.dirname(module.__file__)
85 top_dir = os.path.normpath(os.path.join(os.path.dirname(module.__file__), '..'))
86 self._loader.discover_calls.append((start_dir, pattern, top_dir))
88 def Main(self, argv=None):
92 parser = optparse.OptionParser()
93 parser.add_option('--py-only', action='store_true',
94 help='Runs only python based tests')
95 options, args = parser.parse_args(argv[1:])
98 PY_ONLY_TESTS = options.py_only
100 runner = _RunnerImpl(filters=args)
101 return unittest.main(module=__name__, argv=[sys.argv[0]],
102 testLoader=self._loader,