1 #!/usr/bin/env python 2 # Copyright 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. 5 6 import optparse 7 import os 8 import re 9 import sys 10 import unittest 11 12 13 def main(): 14 parser = optparse.OptionParser() 15 parser.usage = 'run_mojo_python_tests.py [options] [tests...]' 16 parser.add_option('-v', '--verbose', action='count', default=0) 17 parser.add_option('--unexpected-failures', metavar='FILENAME', action='store', 18 help=('path to write a list of any tests that fail ' 19 'unexpectedly.')) 20 parser.epilog = ('If --unexpected-failures is passed, a list of the tests ' 21 'that failed (one per line) will be written to the file. ' 22 'If no tests failed, the file will be truncated (empty). ' 23 'If the test run did not completely properly, or something ' 24 'else weird happened, any existing file will be left ' 25 'unmodified. ' 26 'If --unexpected-failures is *not* passed, any existing ' 27 'file will be ignored and left unmodified.') 28 options, args = parser.parse_args() 29 30 chromium_src_dir = os.path.join(os.path.dirname(__file__), 31 os.pardir, 32 os.pardir) 33 34 loader = unittest.loader.TestLoader() 35 print "Running Python unit tests under mojo/public/tools/bindings/pylib ..." 36 37 pylib_dir = os.path.join(chromium_src_dir, 'mojo', 'public', 38 'tools', 'bindings', 'pylib') 39 if args: 40 if not pylib_dir in sys.path: 41 sys.path.append(pylib_dir) 42 suite = unittest.TestSuite() 43 for test_name in args: 44 suite.addTests(loader.loadTestsFromName(test_name)) 45 else: 46 suite = loader.discover(pylib_dir, pattern='*_unittest.py') 47 48 runner = unittest.runner.TextTestRunner(verbosity=(options.verbose + 1)) 49 result = runner.run(suite) 50 51 if options.unexpected_failures: 52 WriteUnexpectedFailures(result, options.unexpected_failures) 53 54 return 0 if result.wasSuccessful() else 1 55 56 57 def WriteUnexpectedFailures(result, path): 58 59 # This regex and UnitTestName() extracts the test_name in a way 60 # that can be handed back to the loader successfully. 61 62 test_description = re.compile("(\w+) \(([\w.]+)\)") 63 64 def UnitTestName(test): 65 m = test_description.match(str(test)) 66 return "%s.%s" % (m.group(2), m.group(1)) 67 68 with open(path, 'w') as fp: 69 for (test, _) in result.failures + result.errors: 70 fp.write(UnitTestName(test) + '\n') 71 72 73 if __name__ == '__main__': 74 sys.exit(main()) 75