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

Side by Side Diff: chrome/test/webdriver/run_webdriver_tests.py

Issue 7331004: Move chromedriver tests to test subdirectory. Add script to run all chromedriver (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: ... Created 9 years, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/test/webdriver/iframe_src.html ('k') | chrome/test/webdriver/state_zip_labels.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/python
2
3 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 import logging
8 import optparse
9 import os
10 import sys
11 import types
12 import unittest
13
14 from chromedriver_launcher import ChromeDriverLauncher
15 import chromedriver_paths
16 from gtest_text_test_runner import GTestTextTestRunner
17
18 # Add the PYTHON_BINDINGS first so that our 'test' module is found instead of
19 # Python's.
20 sys.path = [chromedriver_paths.PYTHON_BINDINGS] + sys.path
21
22 from selenium.webdriver.remote.webdriver import WebDriver
23
24
25 # Implementation inspired from unittest.main()
26 class Main(object):
27 """Main program for running WebDriver tests."""
28
29 _options, _args = None, None
30 TESTS_FILENAME = 'WEBDRIVER_TESTS'
31 _platform_map = {
32 'win32': 'win',
33 'darwin': 'mac',
34 'linux2': 'linux',
35 'linux3': 'linux',
36 }
37 TEST_PREFIX = 'selenium.test.selenium.webdriver.common.'
38
39 def __init__(self):
40 self._tests_path = os.path.join(os.path.dirname(__file__),
41 self.TESTS_FILENAME)
42 self._ParseArgs()
43 self._Run()
44
45 def _ParseArgs(self):
46 """Parse command line args."""
47 parser = optparse.OptionParser()
48 parser.add_option(
49 '-v', '--verbose', action='store_true', default=False,
50 help='Output verbosely.')
51 parser.add_option(
52 '', '--log-file', type='string', default=None,
53 help='Provide a path to a file to which the logger will log')
54 parser.add_option(
55 '', '--driver-exe', type='string', default=None,
56 help='Path to the ChromeDriver executable.')
57
58 self._options, self._args = parser.parse_args()
59
60 # Setup logging - start with defaults
61 level = logging.WARNING
62 format = None
63
64 if self._options.verbose:
65 level=logging.DEBUG
66 format='%(asctime)s %(levelname)-8s %(message)s'
67
68 logging.basicConfig(level=level, format=format,
69 filename=self._options.log_file)
70
71 @staticmethod
72 def _IsTestClass(obj):
73 """Returns whether |obj| is a unittest.TestCase."""
74 return isinstance(obj, (type, types.ClassType)) and \
75 issubclass(obj, unittest.TestCase)
76
77 @staticmethod
78 def _GetModuleFromName(test_name):
79 """Return the module from the given test name.
80
81 Args:
82 test_name: dot-separated string for a module, a test case or a test
83 method
84 Examples: omnibox (a module)
85 omnibox.OmniboxTest (a test case)
86 omnibox.OmniboxTest.testA (a test method)
87
88 Returns:
89 tuple with first item corresponding to the module and second item
90 corresponding to the parts of the name that did not specify the module
91 Example: _GetModuleFromName('my_module.MyClass.testThis') returns
92 (my_module, ['MyClass', 'testThis'])
93 """
94 parts = test_name.split('.')
95 parts_copy = parts[:]
96 while parts_copy:
97 try:
98 module = __import__('.'.join(parts_copy))
99 break
100 except ImportError:
101 del parts_copy[-1]
102 if not parts_copy: raise
103
104 for comp in parts[1:]:
105 if type(getattr(module, comp)) is not types.ModuleType:
106 break
107 module = getattr(module, comp)
108 return (module, parts[len(parts_copy):])
109
110 @staticmethod
111 def _GetTestClassFromName(test_name):
112 """Return the class for this test or None."""
113 (obj, parts) = Main._GetModuleFromName(test_name)
114 for comp in parts:
115 if not Main._IsTestClass(getattr(obj, comp)):
116 break
117 obj = getattr(obj, comp)
118 if Main._IsTestClass(obj):
119 return obj
120 return None
121
122 @staticmethod
123 def _SetTestClassAttributes(test_name, attribute_name, value):
124 """Sets attributes for all the test classes found from |test_name|.
125
126 Args:
127 test_name: name of the test
128 attribute_name: name of the attribute to set
129 value: value to set the attribute to
130 """
131 class_obj = Main._GetTestClassFromName(test_name)
132 if class_obj is not None:
133 class_objs = [class_obj]
134 else:
135 class_objs = []
136 module, = Main._GetModuleFromName(class_obj)
137 for name in dir(module):
138 item = getattr(module, name)
139 if type(item) is type.TypeType:
140 class_objs += [item]
141 for c in class_objs:
142 setattr(c, attribute_name, value)
143
144 @staticmethod
145 def _GetTestsFromName(name):
146 """Get a list of all test names from the given string.
147
148 Args:
149 name: dot-separated string for a module, a test case or a test method.
150 Examples: omnibox (a module)
151 omnibox.OmniboxTest (a test case)
152 omnibox.OmniboxTest.testA (a test method)
153
154 Returns:
155 [omnibox.OmniboxTest.testA, omnibox.OmniboxTest.testB, ...]
156 """
157 def _GetTestsFromTestCase(class_obj):
158 """Return all test method names from given class object."""
159 return [class_obj.__name__ + '.' + x for x in dir(class_obj) if
160 x.startswith('test')]
161
162 def _GetTestsFromModule(module):
163 """Return all test method names from the given module object."""
164 tests = []
165 for name in dir(module):
166 obj = getattr(module, name)
167 if Main._IsTestClass(obj):
168 tests.extend([module.__name__ + '.' + x for x in
169 _GetTestsFromTestCase(obj)])
170 return tests
171 (obj, parts) = Main._GetModuleFromName(name)
172 for comp in parts:
173 obj = getattr(obj, comp)
174
175 if type(obj) == types.ModuleType:
176 return _GetTestsFromModule(obj)
177 elif Main._IsTestClass(obj):
178 return [module.__name__ + '.' + x for x in _GetTestsFromTestCase(obj)]
179 elif type(obj) == types.UnboundMethodType:
180 return [name]
181 else:
182 logging.warn('No tests in "%s"' % name)
183 return []
184
185 def _HasTestCases(self, module_string):
186 """Determines if we have any test case classes in the module
187 identified by |module_string|."""
188 module = __import__(module_string)
189 for name in dir(module):
190 obj = getattr(module, name)
191 if Main._IsTestClass(obj):
192 return True
193 return False
194
195 def _GetTestNames(self, args):
196 """Returns a suite of tests loaded from the given args.
197
198 The given args can be either a module (ex: module1) or a testcase
199 (ex: module2.MyTestCase) or a test (ex: module1.MyTestCase.testX)
200 If empty, the tests in the already imported modules are loaded.
201
202 Args:
203 args: [module1, module2, module3.testcase, module4.testcase.testX]
204 These modules or test cases or tests should be importable
205 """
206 if not args: # Load tests ourselves
207 logging.debug("Reading %s", self._tests_path)
208 if not os.path.exists(self._tests_path):
209 logging.warn("%s missing. Cannot load tests." % self._tests_path)
210 else:
211 args = self._GetTestNamesFrom(self._tests_path)
212 return args
213
214 @staticmethod
215 def _EvalDataFrom(filename):
216 """Return eval of python code from given file.
217
218 The datastructure used in the file will be preserved.
219 """
220 data_file = os.path.join(filename)
221 contents = open(data_file).read()
222 try:
223 ret = eval(contents, {'__builtins__': None}, None)
224 except:
225 print >>sys.stderr, '%s is an invalid data file.' % data_file
226 raise
227 return ret
228
229 def _GetTestNamesFrom(self, filename):
230 modules = self._EvalDataFrom(filename)
231 all_names = modules.get('all', []) + \
232 modules.get(self._platform_map[sys.platform], [])
233 args = []
234 excluded = []
235 # Find all excluded tests. Excluded tests begin with '-'.
236 for name in all_names:
237 if name.startswith('-'): # Exclude
238 excluded.extend(self._GetTestsFromName(self.TEST_PREFIX + name[1:]))
239 else:
240 args.extend(self._GetTestsFromName(self.TEST_PREFIX + name))
241 for name in excluded:
242 args.remove(name)
243 if excluded:
244 logging.debug('Excluded %d test(s): %s' % (len(excluded), excluded))
245 return args
246
247 def _FakePytestHack(self):
248 """Adds a fake 'pytest' module to the system modules.
249
250 A single test in text_handling_tests.py depends on the pytest module for
251 its test skipping capabilities. Without pytest, we can not run any tests
252 in the text_handling_tests.py module.
253
254 We are not sure we want to add pytest to chrome's third party dependencies,
255 so for now create a fake pytest module so that we can at least import and
256 run all the tests that do not depend on it. Those depending on it are
257 disabled.
258 """
259 import imp
260 sys.modules['pytest'] = imp.new_module('pytest')
261 sys.modules['pytest'].mark = imp.new_module('mark')
262 sys.modules['pytest'].mark.ignore_chrome = lambda x: x
263
264 def _Run(self):
265 """Run the tests."""
266 # TODO(kkania): Remove this hack.
267 self._FakePytestHack()
268
269 test_names = self._GetTestNames(self._args)
270
271 # The tests expect to run with preset 'driver' and 'webserver' class
272 # properties.
273 launcher = ChromeDriverLauncher(self._options.driver_exe,
274 chromedriver_paths.WEBDRIVER_TEST_DATA)
275 driver = WebDriver(launcher.GetURL(), {})
276 # The tests expect a webserver. Since ChromeDriver also operates as one,
277 # just pass this dummy class with the right info.
278 class DummyWebserver:
279 pass
280 webserver = DummyWebserver()
281 webserver.port = launcher.GetPort()
282 for test in test_names:
283 Main._SetTestClassAttributes(test, 'driver', driver)
284 Main._SetTestClassAttributes(test, 'webserver', webserver)
285
286 # Load and run the tests.
287 logging.debug('Loading tests from %s', test_names)
288 loaded_tests = unittest.defaultTestLoader.loadTestsFromNames(test_names)
289 test_suite = unittest.TestSuite()
290 test_suite.addTests(loaded_tests)
291 verbosity = 1
292 if self._options.verbose:
293 verbosity = 2
294 result = GTestTextTestRunner(verbosity=verbosity).run(test_suite)
295 launcher.Kill()
296 sys.exit(not result.wasSuccessful())
297
298
299 if __name__ == '__main__':
300 Main()
OLDNEW
« no previous file with comments | « chrome/test/webdriver/iframe_src.html ('k') | chrome/test/webdriver/state_zip_labels.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698