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

Side by Side Diff: scripts/slave/unittests/expect_tests/unittest_helper.py

Issue 354913003: Add module discovery and autoloading to expect_tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: add --force_coverage option Created 6 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
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 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 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import unittest 5 import unittest
6 6
7 from .type_definitions import Test, Result, MultiTest, FuncCall, Bind 7 from .type_definitions import Test, Result, MultiTest, FuncCall, Bind
8 8
9 from .util import covers
10
9 11
10 def _SetUpClass(test_class): 12 def _SetUpClass(test_class):
11 inst = test_class('__init__') 13 inst = test_class('__init__')
12 inst.setUpClass() 14 inst.setUpClass()
13 return inst 15 return inst
14 16
15 17
16 def _TearDownClass(test_class_inst): 18 def _TearDownClass(test_class_inst):
17 test_class_inst.tearDownClass() 19 test_class_inst.tearDownClass()
18 20
19 21
20 def _RunTestCaseSingle(test_case, test_name, test_instance=None): 22 def _RunTestCaseSingle(test_case, test_name, test_instance=None):
21 # The hack is so that unittest.TestCase has something to pretend is the 23 # The hack is so that unittest.TestCase has something to pretend is the
22 # test method without the BS of wrapping each method in a new TestCase 24 # test method without the BS of wrapping each method in a new TestCase
23 # class... 25 # class...
24 test_instance = test_instance or test_case('__init__') 26 test_instance = test_instance or test_case('__init__')
25 test_instance.setUp() 27 test_instance.setUp()
26 try: 28 try:
27 return Result(getattr(test_instance, test_name)()) 29 return Result(getattr(test_instance, test_name)())
28 finally: 30 finally:
29 test_instance.tearDown() 31 test_instance.tearDown()
30 32
31 33
32 def UnittestTestCase(test_case, name_prefix='', ext='json'): 34 def UnittestTestCase(test_case):
33 """Yield a MultiTest or multiple Test instances for the unittest.TestCase 35 """Yield a MultiTest or multiple Test instances for the unittest.TestCase
34 derived |test_case|. 36 derived |test_case|.
35 37
36 If the TestCase has a field `__expect_tests_serial__` defined to be True, then 38 If the TestCase has a field `__expect_tests_serial__` defined to be True, then
37 all test methods in the TestCase will be guaranteed to run in a single process 39 all test methods in the TestCase will be guaranteed to run in a single process
38 with the same instance. This is automatically set to True if your test class 40 with the same instance. This is automatically set to True if your test class
39 relies on setUpClass/tearDownClass. 41 relies on setUpClass/tearDownClass.
40 42
41 If the TestCase has a field `__expect_tests_atomic__` defined to be True, then 43 If the TestCase has a field `__expect_tests_atomic__` defined to be True, then
42 in the event of a test filter which matches any test method in |test_case|, 44 in the event of a test filter which matches any test method in |test_case|,
43 the ENTIRE |test_case| will be executed (i.e. the TestCase has interdependant 45 the ENTIRE |test_case| will be executed (i.e. the TestCase has interdependant
44 test methods). This should only need to be set for very poorly designed tests. 46 test methods). This should only need to be set for very poorly designed tests.
45 47
46 `__expect_tests_atomic__` implies `__expect_tests_serial__`. 48 `__expect_tests_atomic__` implies `__expect_tests_serial__`.
47 49
48 @type test_case: unittest.TestCase 50 @type test_case: unittest.TestCase
49 """ 51 """
50 name_prefix = name_prefix + test_case.__name__ 52 @covers(lambda: Test.covers_obj(test_case))
51 def _tests_from_class(cls, *args, **kwargs): 53 def _inner():
52 for test_name in unittest.defaultTestLoader.getTestCaseNames(cls): 54 name_prefix = '.'.join((test_case.__module__, test_case.__name__))
53 yield Test( 55
54 name_prefix + '.' + test_name, 56 def _tests_from_class(cls, *args, **kwargs):
55 FuncCall(_RunTestCaseSingle, cls, test_name, *args, **kwargs), 57 for test_name in unittest.defaultTestLoader.getTestCaseNames(cls):
56 ext=ext, break_funcs=[getattr(cls, test_name)], 58 yield Test(
59 name_prefix + '.' + test_name,
60 FuncCall(_RunTestCaseSingle, cls, test_name, *args, **kwargs),
61 expect_dir=Test.expect_dir_obj(cls),
62 expect_base=cls.__name__ + '.' + test_name,
63 break_funcs=[getattr(cls, test_name)],
64 covers=Test.covers_obj(cls)
65 )
66
67 if hasattr(test_case, '__expect_tests_serial__'):
68 serial = getattr(test_case, '__expect_tests_serial__', False)
69 else:
70 default_setup = unittest.TestCase.setUpClass.im_func
71 default_teardown = unittest.TestCase.tearDownClass.im_func
72 serial = (
73 test_case.setUpClass.im_func is not default_setup or
74 test_case.tearDownClass.im_func is not default_teardown)
75
76 atomic = getattr(test_case, '__expect_tests_atomic__', False)
77 if atomic or serial:
78 yield MultiTest(
79 name_prefix,
80 FuncCall(_SetUpClass, test_case),
81 FuncCall(_TearDownClass, Bind(name='context')),
82 list(_tests_from_class(test_case,
83 test_instance=Bind(name='context'))),
84 atomic
57 ) 85 )
58 86 else:
59 if hasattr(test_case, '__expect_tests_serial__'): 87 for test in _tests_from_class(test_case):
60 serial = getattr(test_case, '__expect_tests_serial__', False) 88 yield test
61 else: 89 return _inner
62 default_setup = unittest.TestCase.setUpClass.im_func
63 default_teardown = unittest.TestCase.tearDownClass.im_func
64 serial = (
65 test_case.setUpClass.im_func is not default_setup or
66 test_case.tearDownClass.im_func is not default_teardown)
67
68 atomic = getattr(test_case, '__expect_tests_atomic__', False)
69 if atomic or serial:
70 yield MultiTest(
71 name_prefix,
72 FuncCall(_SetUpClass, test_case),
73 FuncCall(_TearDownClass, Bind(name='context')),
74 list(_tests_from_class(test_case, test_instance=Bind(name='context'))),
75 atomic
76 )
77 else:
78 for test in _tests_from_class(test_case):
79 yield test
80 90
81 91
82 def UnitTestModule(test_module, name_prefix='', ext='json'): 92 def _is_unittest(obj):
93 if isinstance(obj, type) and issubclass(obj, unittest.TestCase):
Vadim Sh. 2014/06/27 21:40:08 nit: return isinstance(...) and ... or "return Fal
iannucci 2014/06/28 16:22:17 derp, of course
94 return True
95
96
97 def UnitTestModule(test_module):
83 """Yield MultiTest's and/or Test's for the python module |test_module| which 98 """Yield MultiTest's and/or Test's for the python module |test_module| which
84 contains zero or more unittest.TestCase implementations. 99 contains zero or more unittest.TestCase implementations.
85 100
86 @type test_module: types.ModuleType 101 @type test_module: types.ModuleType
87 """ 102 """
88 name_prefix = name_prefix + test_module.__name__ + '.'
89 for name in dir(test_module): 103 for name in dir(test_module):
90 obj = getattr(test_module, name) 104 obj = getattr(test_module, name)
91 if isinstance(obj, type) and issubclass(obj, unittest.TestCase): 105 if _is_unittest(obj):
92 for test in UnittestTestCase(obj, name_prefix, ext): 106 for test in UnittestTestCase(obj)():
93 yield test 107 yield test
94 # TODO(iannucci): Make this compatible with the awful load_tests hack? 108 # TODO(iannucci): Make this compatible with the awful load_tests hack?
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698