1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
10 from tvcm import dev_server
11 from tvcm import browser_controller
12 from tvcm import test_runner
13 from tvcm import resource_loader
16 _currently_active_module_test_suite = None
19 def _NavigateToTestCaseRunner(bc):
20 bc.NavigateToPath('/tvcm/unittest/module_test_case_runner.html')
21 bc.WaitForJavaScriptExpression('window.__readyToRun == true')
22 # Sanity checks that __readyToRun is working right. If any of these pop,
23 # it implies that __readyToRun isn't working.
25 'window.tvcm !== undefined',
26 'window.tvcm.GUID.allocate !== undefined',
27 'window.tvcm.hasPanic !== undefined',
28 'window.discoverTestsInModules !== undefined',
29 'window.runTestNamed !== undefined'
31 for check in sanity_checks:
32 if not bc.EvaluateJavaScript(check):
33 raise Exception('Load failed because sanity check %s failed')
36 class ModuleTestSuite(unittest.TestSuite):
37 def __init__(self, project):
38 super(ModuleTestSuite, self).__init__()
39 self._project = project
41 self._bc_startup_exception_string = None
46 return self.recreateEmptyVersion()
48 def recreateEmptyVersion(self):
49 return ModuleTestSuite(self._project)
51 def __call__(self, *args):
52 return self.run(*args)
54 def run(self, result):
57 return super(ModuleTestSuite, self).run(result)
66 def bc_startup_exception_string(self):
67 return self._bc_startup_exception_string
70 global _currently_active_module_test_suite
71 if _currently_active_module_test_suite:
72 self._bc_startup_exception_string = "Some previous suite did not shut down cleanly"
77 self._bc = browser_controller.BrowserController(self._project)
78 _NavigateToTestCaseRunner(self._bc)
82 self._bc_startup_exception_string = traceback.format_exc()
86 _currently_active_module_test_suite = self
88 self._bc.stdout_enabled = True
92 self._bc.stdout_enabled = False
96 global _currently_active_module_test_suite
97 _currently_active_module_test_suite = None
99 def DiscoverTestsInModule(project, start_path):
101 return _DiscoverTestsInModuleImpl(project, start_path)
104 sys.stderr.write("While discovering tests:\n")
105 sys.stderr.write(sys.exc_info()[1].message)
106 sys.stderr.write("\n\n")
109 def _DiscoverTestsInModuleImpl(project, start_path):
110 if test_runner.PY_ONLY_TESTS:
111 return unittest.TestSuite()
113 if not browser_controller.IsSupported():
114 raise Exception('Cannot run all tests: telemetry could not be found')
115 rl = resource_loader.ResourceLoader(project)
117 test_modules = [x.name for x in
118 project.FindAllTestModuleResources(start_path=start_path)]
120 bc = browser_controller.BrowserController(project)
122 _NavigateToTestCaseRunner(bc)
123 if bc.EvaluateJavaScript('tvcm.hasPanic()'):
124 raise Exception('Runner failure: %s' % bc.EvaluateJavaScript('tvcm.getPanicText()'))
126 tests = bc.EvaluateThennableAndWait(
127 'discoverTestsInModules(%s)' % json.dumps(test_modules))
129 if bc.EvaluateJavaScript('tvcm.hasPanic()'):
130 raise Exception('Test loading failure: %s' % bc.EvaluateJavaScript('tvcm.getPanicText()'))
132 suite = ModuleTestSuite(project)
133 for fully_qualified_test_name in tests:
134 suite.addTest(ModuleTestCase(fully_qualified_test_name))
141 class ModuleTestCase(unittest.TestCase):
142 def __init__(self, fully_qualified_test_name):
143 super(ModuleTestCase, self).__init__(methodName='runTest')
144 self.fully_qualified_test_name = fully_qualified_test_name
147 return self.fully_qualified_test_name
149 def shortDescription(self):
153 i = self.fully_qualified_test_name.rfind('.')
154 modname = self.fully_qualified_test_name[0:i]
155 testname = self.fully_qualified_test_name[i+1:]
156 return '%s (%s)' % (testname, modname)
159 global _currently_active_module_test_suite
160 mts = _currently_active_module_test_suite
161 assert mts, 'Something is wrong: ModuleTestCase can only be run inside a ModuleTestSuite.run()'
164 raise Exception('Test cannot run because browser did not start.\n\nOriginal %s\n\n' % \
165 mts.bc_startup_exception_string)
167 res = bc.EvaluateThennableAndWait(
168 'runTestNamed(%s)' % json.dumps(self.fully_qualified_test_name))