Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Unified Diff: scripts/slave/unittests/expect_tests/main.py

Issue 354913003: Add module discovery and autoloading to expect_tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Fix formatting + comment Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: scripts/slave/unittests/expect_tests/main.py
diff --git a/scripts/slave/unittests/expect_tests/main.py b/scripts/slave/unittests/expect_tests/main.py
index 5a266b1136eea7e6caff7030d0a86a12a56c3bfe..ba10440d7bc4abaf86e6becd2a3c0af1648520dd 100644
--- a/scripts/slave/unittests/expect_tests/main.py
+++ b/scripts/slave/unittests/expect_tests/main.py
@@ -4,14 +4,20 @@
import argparse
import multiprocessing
+import pkgutil
import sys
from .cover import CoverageContext
-from . import handle_list, handle_debug, handle_train, handle_test
+from . import handle_list, handle_debug, handle_train, handle_test, util
from .pipeline import result_loop
+from .unittest_helper import _is_unittest, UnittestTestCase
+
+
+ALL_MODULES = object()
+
HANDLERS = {
'list': handle_list.ListHandler,
@@ -35,8 +41,8 @@ class _test_completer(object):
for k, v in kwargs.iteritems():
setattr(self, k, v)
- def __init__(self, gen):
- self._gen = gen
+ def __init__(self, test_modules):
+ self._test_modules = test_modules
def __call__(self, prefix, **_):
handle_list.ListHandler.COMPLETION_LIST = []
@@ -45,12 +51,13 @@ class _test_completer(object):
test_glob=[prefix],
jobs=1,
)
- ctx = CoverageContext('', [], [], False, None, None, False)
- result_loop(self._gen, ctx.create_subprocess_context(), options)
+ ctx = CoverageContext(False, False, False)
+ test_gens = get_test_gens(self._test_modules)
+ result_loop(test_gens, ctx.create_subprocess_context(), options)
return handle_list.ListHandler.COMPLETION_LIST
-def _parse_args(args, test_gen):
+def _parse_args(args, test_modules):
args = args or sys.argv[1:]
# Set the default mode if not specified and not passing --help
@@ -83,6 +90,10 @@ def _parse_args(args, test_gen):
default=multiprocessing.cpu_count(),
help='run N jobs in parallel (default %(default)s)')
+ sp.add_argument(
+ '--force_coverage', action='store_true',
+ help='Enable coverage report even when specifying a test filter.')
+
sp.add_argument(
'--test_list', metavar='FILE',
help='take the list of test globs from the FILE (use "-" for stdin)'
@@ -99,7 +110,7 @@ def _parse_args(args, test_gen):
'then it acts as a negation glob and anything which matches it '
'will be skipped. If a glob doesn\'t have "*" in it, "*" will be '
'implicitly appended to the end')
- ).completer = _test_completer(test_gen)
+ ).completer = _test_completer(test_modules)
opts = parser.parse_args(args)
@@ -121,40 +132,73 @@ def _parse_args(args, test_gen):
return opts
-def main(name, test_gen, cover_branches=False, args=None):
+def get_test_gens(test_modules):
+ test_gens = []
+ if not test_modules or test_modules is ALL_MODULES:
+ # if we're running directly
+ if __name__ == '__main__' or test_modules is ALL_MODULES:
+ test_modules = []
+ for importer, modname, ispkg in pkgutil.walk_packages(path=['.']):
+ if not ispkg and modname.endswith('_test'):
+ if modname in sys.modules:
+ test_modules.append(sys.modules[modname])
+ else:
+ test_modules.append(
+ importer.find_module(modname).load_module(modname))
+ else: # a wrapper main() script
+ test_modules = [sys.modules['__main__']]
+ for mod in test_modules:
+ for obj in mod.__dict__.values():
+ if util.is_test_generator(obj):
+ test_gens.append(obj)
+ elif _is_unittest(obj):
+ test_gens.append(UnittestTestCase(obj))
+ return test_gens
+
+
+# TODO(iannucci): have Test determine cover_branches
+def main(cover_branches=False, test_modules=None, args=None):
"""Entry point for tests using expect_tests.
Example:
- import expect_tests
+ >>> import expect_tests
- def happy_fn(val):
- # Usually you would return data which is the result of some deterministic
- # computation.
- return expect_tests.Result({'neet': '%s string value' % val})
+ >>> def happy_fn(val):
+ >>> # Usually you would return data which is the result of some
+ >>> #deterministic computation.
+ >>> return expect_tests.Result({'neet': '%s string value' % val})
- def Gen():
- yield expect_tests.Test('happy', happy_fn, args=('happy',))
+ >>> @expect_tests.test_generator
+ >>> def gen():
+ >>> yield expect_tests.Test(
+ >>> __package__ + '.happy',
+ >>> expect_tests.FuncCall(happy_fn, 'happy'))
- if __name__ == '__main__':
- expect_tests.main('happy_test_suite', Gen)
+ >>> if __name__ == '__main__':
+ >>> expect_tests.main(cover_branches=True)
- @param name: Name of the test suite.
- @param test_gen: A Generator which yields Test objects.
@param cover_branches: Include branch coverage data (rather than just line
coverage)
+ @param test_modules: Modules containing expect_tests generators and/or
+ unittests. Defaults to the __main__ module, or if
+ this script is invoked directly, all '_test' modules
+ under the current working directory.
@param args: Commandline args (starting at argv[1])
"""
try:
- opts = _parse_args(args, test_gen)
+ opts = _parse_args(args, test_modules)
- cover_ctx = CoverageContext(name, cover_branches, opts.html_report,
+ cover_ctx = CoverageContext(cover_branches, opts.html_report,
not opts.handler.SKIP_RUNLOOP)
+ with cover_ctx.create_subprocess_context():
+ test_gens = get_test_gens(test_modules)
+
error, killed = result_loop(
- test_gen, cover_ctx.create_subprocess_context(), opts)
+ test_gens, cover_ctx.create_subprocess_context(), opts)
cover_ctx.cleanup()
- if not killed and not opts.test_glob:
+ if not killed and (opts.force_coverage or not opts.test_glob):
if not cover_ctx.report(opts.verbose):
sys.exit(2)

Powered by Google App Engine
This is Rietveld 408576698