/chrome/test/chromedriver/test/run_java_tests.py
https://gitlab.com/jonnialva90/iridium-browser · Python · 334 lines · 285 code · 15 blank · 34 comment · 7 complexity · d46eaee9a8c04bbc7a8af6083be5f992 MD5 · raw file
- #!/usr/bin/env python
- # Copyright 2013 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """Runs the WebDriver Java acceptance tests.
- This script is called from chrome/test/chromedriver/run_all_tests.py and reports
- results using the buildbot annotation scheme.
- For ChromeDriver documentation, refer to http://code.google.com/p/chromedriver.
- """
- import optparse
- import os
- import shutil
- import sys
- import xml.dom.minidom as minidom
- _THIS_DIR = os.path.abspath(os.path.dirname(__file__))
- sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir))
- import chrome_paths
- import test_environment
- import util
- if util.IsLinux():
- sys.path.insert(0, os.path.join(chrome_paths.GetSrc(), 'build', 'android'))
- from pylib import constants
- class TestResult(object):
- """A result for an attempted single test case."""
- def __init__(self, name, time, failure):
- """Initializes a test result.
- Args:
- name: the full name of the test.
- time: the amount of time the test ran, in seconds.
- failure: the test error or failure message, or None if the test passed.
- """
- self._name = name
- self._time = time
- self._failure = failure
- def GetName(self):
- """Returns the test name."""
- return self._name
- def GetTime(self):
- """Returns the time it took to run the test."""
- return self._time
- def IsPass(self):
- """Returns whether the test passed."""
- return self._failure is None
- def GetFailureMessage(self):
- """Returns the test failure message, or None if the test passed."""
- return self._failure
- def _Run(java_tests_src_dir, test_filter,
- chromedriver_path, chrome_path, log_path, android_package_key,
- verbose, debug):
- """Run the WebDriver Java tests and return the test results.
- Args:
- java_tests_src_dir: the java test source code directory.
- test_filter: the filter to use when choosing tests to run. Format is same
- as Google C++ Test format.
- chromedriver_path: path to ChromeDriver exe.
- chrome_path: path to Chrome exe.
- log_path: path to server log.
- android_package_key: name of Chrome's Android package.
- verbose: whether the output should be verbose.
- debug: whether the tests should wait until attached by a debugger.
- Returns:
- A list of |TestResult|s.
- """
- test_dir = util.MakeTempDir()
- keystore_path = ('java', 'client', 'test', 'keystore')
- required_dirs = [keystore_path[:-1],
- ('javascript',),
- ('third_party', 'closure', 'goog'),
- ('third_party', 'js')]
- for required_dir in required_dirs:
- os.makedirs(os.path.join(test_dir, *required_dir))
- test_jar = 'test-standalone.jar'
- class_path = test_jar
- shutil.copyfile(os.path.join(java_tests_src_dir, 'keystore'),
- os.path.join(test_dir, *keystore_path))
- util.Unzip(os.path.join(java_tests_src_dir, 'common.zip'), test_dir)
- shutil.copyfile(os.path.join(java_tests_src_dir, test_jar),
- os.path.join(test_dir, test_jar))
- sys_props = ['selenium.browser=chrome',
- 'webdriver.chrome.driver=' + os.path.abspath(chromedriver_path)]
- if chrome_path:
- sys_props += ['webdriver.chrome.binary=' + os.path.abspath(chrome_path)]
- if log_path:
- sys_props += ['webdriver.chrome.logfile=' + log_path]
- if android_package_key:
- android_package = constants.PACKAGE_INFO[android_package_key].package
- sys_props += ['webdriver.chrome.android_package=' + android_package]
- if android_package_key == 'chromedriver_webview_shell':
- android_activity = constants.PACKAGE_INFO[android_package_key].activity
- android_process = '%s:main' % android_package
- sys_props += ['webdriver.chrome.android_activity=' + android_activity]
- sys_props += ['webdriver.chrome.android_process=' + android_process]
- if test_filter:
- # Test jar actually takes a regex. Convert from glob.
- test_filter = test_filter.replace('*', '.*')
- sys_props += ['filter=' + test_filter]
- jvm_args = []
- if debug:
- transport = 'dt_socket'
- if util.IsWindows():
- transport = 'dt_shmem'
- jvm_args += ['-agentlib:jdwp=transport=%s,server=y,suspend=y,'
- 'address=33081' % transport]
- # Unpack the sources into the test directory and add to the class path
- # for ease of debugging, particularly with jdb.
- util.Unzip(os.path.join(java_tests_src_dir, 'test-nodeps-srcs.jar'),
- test_dir)
- class_path += ':' + test_dir
- return _RunAntTest(
- test_dir, 'org.openqa.selenium.chrome.ChromeDriverTests',
- class_path, sys_props, jvm_args, verbose)
- def _RunAntTest(test_dir, test_class, class_path, sys_props, jvm_args, verbose):
- """Runs a single Ant JUnit test suite and returns the |TestResult|s.
- Args:
- test_dir: the directory to run the tests in.
- test_class: the name of the JUnit test suite class to run.
- class_path: the Java class path used when running the tests, colon delimited
- sys_props: Java system properties to set when running the tests.
- jvm_args: Java VM command line args to use.
- verbose: whether the output should be verbose.
- Returns:
- A list of |TestResult|s.
- """
- def _CreateBuildConfig(test_name, results_file, class_path, junit_props,
- sys_props, jvm_args):
- def _SystemPropToXml(prop):
- key, value = prop.split('=')
- return '<sysproperty key="%s" value="%s"/>' % (key, value)
- def _JvmArgToXml(arg):
- return '<jvmarg value="%s"/>' % arg
- return '\n'.join([
- '<project>',
- ' <target name="test">',
- ' <junit %s>' % ' '.join(junit_props),
- ' <formatter type="xml"/>',
- ' <classpath>',
- ' <pathelement path="%s"/>' % class_path,
- ' </classpath>',
- ' ' + '\n '.join(map(_SystemPropToXml, sys_props)),
- ' ' + '\n '.join(map(_JvmArgToXml, jvm_args)),
- ' <test name="%s" outfile="%s"/>' % (test_name, results_file),
- ' </junit>',
- ' </target>',
- '</project>'])
- def _ProcessResults(results_path):
- doc = minidom.parse(results_path)
- tests = []
- for test in doc.getElementsByTagName('testcase'):
- name = test.getAttribute('classname') + '.' + test.getAttribute('name')
- time = test.getAttribute('time')
- failure = None
- error_nodes = test.getElementsByTagName('error')
- failure_nodes = test.getElementsByTagName('failure')
- if error_nodes:
- failure = error_nodes[0].childNodes[0].nodeValue
- elif failure_nodes:
- failure = failure_nodes[0].childNodes[0].nodeValue
- tests += [TestResult(name, time, failure)]
- return tests
- junit_props = ['printsummary="yes"',
- 'fork="yes"',
- 'haltonfailure="no"',
- 'haltonerror="no"']
- if verbose:
- junit_props += ['showoutput="yes"']
- ant_file = open(os.path.join(test_dir, 'build.xml'), 'w')
- ant_file.write(_CreateBuildConfig(
- test_class, 'results', class_path, junit_props, sys_props, jvm_args))
- ant_file.close()
- if util.IsWindows():
- ant_name = 'ant.bat'
- else:
- ant_name = 'ant'
- code = util.RunCommand([ant_name, 'test'], cwd=test_dir)
- if code != 0:
- print 'FAILED to run java tests of %s through ant' % test_class
- return
- return _ProcessResults(os.path.join(test_dir, 'results.xml'))
- def PrintTestResults(results):
- """Prints the given results in a format recognized by the buildbot."""
- failures = []
- failure_names = []
- for result in results:
- if not result.IsPass():
- failures += [result]
- failure_names += ['.'.join(result.GetName().split('.')[-2:])]
- print 'Ran %s tests' % len(results)
- print 'Failed %s:' % len(failures)
- util.AddBuildStepText('failed %s/%s' % (len(failures), len(results)))
- for result in failures:
- print '=' * 80
- print '=' * 10, result.GetName(), '(%ss)' % result.GetTime()
- print result.GetFailureMessage()
- if len(failures) < 10:
- util.AddBuildStepText('.'.join(result.GetName().split('.')[-2:]))
- print 'Rerun failing tests with filter:', ':'.join(failure_names)
- return len(failures)
- def main():
- parser = optparse.OptionParser()
- parser.add_option(
- '', '--verbose', action='store_true', default=False,
- help='Whether output should be verbose')
- parser.add_option(
- '', '--debug', action='store_true', default=False,
- help='Whether to wait to be attached by a debugger')
- parser.add_option(
- '', '--chromedriver', type='string', default=None,
- help='Path to a build of the chromedriver library(REQUIRED!)')
- parser.add_option(
- '', '--chrome', type='string', default=None,
- help='Path to a build of the chrome binary')
- parser.add_option(
- '', '--log-path',
- help='Output verbose server logs to this file')
- parser.add_option(
- '', '--chrome-version', default='HEAD',
- help='Version of chrome. Default is \'HEAD\'')
- parser.add_option(
- '', '--android-package', help='Android package key')
- parser.add_option(
- '', '--filter', type='string', default=None,
- help='Filter for specifying what tests to run, "*" will run all. E.g., '
- '*testShouldReturnTitleOfPageIfSet')
- parser.add_option(
- '', '--also-run-disabled-tests', action='store_true', default=False,
- help='Include disabled tests while running the tests')
- parser.add_option(
- '', '--isolate-tests', action='store_true', default=False,
- help='Relaunch the jar test harness after each test')
- options, _ = parser.parse_args()
- options.chromedriver = util.GetAbsolutePathOfUserPath(options.chromedriver)
- if options.chromedriver is None or not os.path.exists(options.chromedriver):
- parser.error('chromedriver is required or the given path is invalid.' +
- 'Please run "%s --help" for help' % __file__)
- if options.android_package:
- if options.android_package not in constants.PACKAGE_INFO:
- parser.error('Invalid --android-package')
- if options.chrome_version != 'HEAD':
- parser.error('Android does not support the --chrome-version argument.')
- environment = test_environment.AndroidTestEnvironment(
- options.android_package)
- else:
- environment = test_environment.DesktopTestEnvironment(
- options.chrome_version)
- try:
- environment.GlobalSetUp()
- # Run passed tests when filter is not provided.
- if options.isolate_tests:
- test_filters = environment.GetPassedJavaTests()
- else:
- if options.filter:
- test_filter = options.filter
- else:
- test_filter = '*'
- if not options.also_run_disabled_tests:
- if '-' in test_filter:
- test_filter += ':'
- else:
- test_filter += '-'
- test_filter += ':'.join(environment.GetDisabledJavaTestMatchers())
- test_filters = [test_filter]
- java_tests_src_dir = os.path.join(chrome_paths.GetSrc(), 'chrome', 'test',
- 'chromedriver', 'third_party',
- 'java_tests')
- if (not os.path.exists(java_tests_src_dir) or
- not os.listdir(java_tests_src_dir)):
- java_tests_url = ('http://src.chromium.org/svn/trunk/deps/third_party'
- '/webdriver')
- print ('"%s" is empty or it doesn\'t exist. ' % java_tests_src_dir +
- 'Need to map <chrome-svn>/trunk/deps/third_party/webdriver to '
- 'chrome/test/chromedriver/third_party/java_tests in .gclient.\n'
- 'Alternatively, do:\n'
- ' $ cd chrome/test/chromedriver/third_party\n'
- ' $ svn co %s java_tests' % java_tests_url)
- return 1
- results = []
- for filter in test_filters:
- results += _Run(
- java_tests_src_dir=java_tests_src_dir,
- test_filter=filter,
- chromedriver_path=options.chromedriver,
- chrome_path=util.GetAbsolutePathOfUserPath(options.chrome),
- log_path=options.log_path,
- android_package_key=options.android_package,
- verbose=options.verbose,
- debug=options.debug)
- return PrintTestResults(results)
- finally:
- environment.GlobalTearDown()
- if __name__ == '__main__':
- sys.exit(main())