Skip to content

Commit

Permalink
Address review comments.
Browse files Browse the repository at this point in the history
* Fix logical issues
* Add test coverage for generated tests
  • Loading branch information
xpconanfan committed Aug 30, 2024
1 parent bd0d282 commit 4b4ed5f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 14 deletions.
27 changes: 13 additions & 14 deletions mobly/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1017,39 +1017,38 @@ def _get_test_methods(self, test_names):
This can only be caused by user input.
"""
test_methods = []
# Call once and reuse the list through this function for efficiency.
current_valid_names = self.get_existing_test_names()
# Process the test name selector one by one.
for test_name in test_names:
if test_name.startswith(TEST_SELECTOR_REGEX_PREFIX):
# process the selector as a regex.
regex_matching_methods = self._get_regex_matching_test_methods(
test_name[len(TEST_SELECTOR_REGEX_PREFIX) :], current_valid_names
test_name.removeprefix(TEST_SELECTOR_REGEX_PREFIX)
)
test_methods += regex_matching_methods
continue
# process the selector as a regular test name string.
self._assert_valid_test_name(test_name)
if test_name not in current_valid_names:
raise Error('%s does not have test method %s.' % (self.TAG, test_name))
if test_name not in self.get_existing_test_names():
raise Error(f'{self.TAG} does not have test method {test_name}.')
if hasattr(self, test_name):
test_method = getattr(self, test_name)
elif test_name in self._generated_test_table:
test_method = self._generated_test_table[test_name]
test_methods.append((test_name, test_method))
return test_methods

def _get_regex_matching_test_methods(
self, test_name_regex, current_valid_names
):
def _get_regex_matching_test_methods(self, test_name_regex):
matching_name_tuples = []
for name in current_valid_names:
if re.fullmatch(test_name_regex, name):
matching_name_tuples.append((name, getattr(self, name)))
for name in self._generated_test_table.keys():
if re.fullmatch(test_name_regex, name):
for name, method in inspect.getmembers(self, callable):
if (
name.startswith('test_')
and re.fullmatch(test_name_regex, name) is not None
):
matching_name_tuples.append((name, method))
for name, method in self._generated_test_table.items():
if re.fullmatch(test_name_regex, name) is not None:
self._assert_valid_test_name(name)
matching_name_tuples.append((name, self._generated_test_table[name]))
matching_name_tuples.append((name, method))
if not matching_name_tuples:
raise Error(
f'{test_name_regex} does not match with any valid test case '
Expand Down
32 changes: 32 additions & 0 deletions tests/mobly/base_test_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,38 @@ def test_never(self):
self.assertEqual(bt_cls.results.passed[4].test_name, 'test_a')
self.assertEqual(bt_cls.results.passed[5].test_name, 'test_b')

def test_cli_test_selection_with_regex_generated_tests(self):
class MockBaseTest(base_test.BaseTestClass):

def __init__(self, controllers):
super().__init__(controllers)
self.tests = ('test_never',)

def pre_run(self):
self.generate_tests(
test_logic=self.logic,
name_func=lambda i: f'test_something_{i}',
arg_sets=[(i + 1,) for i in range(3)],
)

def test_foo(self):
pass

def logic(self, _):
pass

def test_never(self):
# This should not execute since it's not selected by cmd line input.
never_call()

bt_cls = MockBaseTest(self.mock_test_cls_configs)
bt_cls.run(test_names=['re:test_something_.*', 'test_foo'])
self.assertEqual(len(bt_cls.results.passed), 4)
self.assertEqual(bt_cls.results.passed[0].test_name, 'test_something_1')
self.assertEqual(bt_cls.results.passed[1].test_name, 'test_something_2')
self.assertEqual(bt_cls.results.passed[2].test_name, 'test_something_3')
self.assertEqual(bt_cls.results.passed[3].test_name, 'test_foo')

def test_cli_test_selection_with_regex_fail_by_convention(self):
class MockBaseTest(base_test.BaseTestClass):

Expand Down

0 comments on commit 4b4ed5f

Please sign in to comment.