Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions test/test_runner_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,14 @@ def test_get_tests_for_suite_in_suite(self):

instance = test_runner.TestRunner(mock.sentinel.test_class)
ret = instance.get_tests_for_suite(mock.sentinel.selected_suite_name)
assert_equal(ret, [self.mock_test_method])
assert_equal(list(ret), [self.mock_test_method])

def test_get_tests_for_suite_not_in_suite(self):
self.in_suite_mock.return_value = False

instance = test_runner.TestRunner(mock.sentinel.test_class)
ret = instance.get_tests_for_suite(mock.sentinel.selected_suite_name)
assert_equal(ret, [])
assert_equal(list(ret), [])


class TestTestRunnerPrintsTestNames(test_case.TestCase):
Expand Down
28 changes: 14 additions & 14 deletions testify/test_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,20 @@ def discover(what):
try:
what = to_module(what)
mod = __import__(what, fromlist=[str('__trash')])
discovered = set()

if hasattr(mod, '__path__'):
# It's a package!
for _, module_name, _ in pkgutil.walk_packages(
mod.__path__,
prefix=mod.__name__ + '.',
):
mod = __import__(module_name, fromlist=[str('__trash')])
discovered.update(get_test_classes_from_module(mod))
else:
discovered.update(get_test_classes_from_module(mod))

return discovered
for cls in get_test_classes_from_module(mod):
yield cls

if not hasattr(mod, '__path__'):
return

# It's a package!
for _, module_name, _ in pkgutil.walk_packages(
mod.__path__,
prefix=mod.__name__ + '.',
):
submod = __import__(module_name, fromlist=[str('__trash')])
for cls in get_test_classes_from_module(submod):
yield cls
except Exception:
traceback.print_exc()
raise DiscoveryError(
Expand Down
4 changes: 0 additions & 4 deletions testify/test_reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ def __init__(self, options):
"""
self.options = options

def test_counts(self, test_case_count, test_method_count):
"""Called after discovery finishes. May not be called by all test runners, e.g. TestRunnerClient."""
pass

def test_start(self, result):
"""Called when a test method is being run. Gets passed a TestResult dict which should not be complete."""
pass
Expand Down
46 changes: 16 additions & 30 deletions testify/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,10 @@ def _construct_test(self, test_case_cls, **kwargs):

def discover(self):
def discover_tests():
return sorted(
[
self._construct_test(test_case_class)
for test_case_class in test_discovery.discover(self.test_path_or_test_case)
if not self.module_method_overrides or test_case_class.__name__ in self.module_method_overrides
],
key=lambda test_case: MetaTestCase._cmp_str(type(test_case)),
return (
self._construct_test(test_case_class)
for test_case_class in test_discovery.discover(self.test_path_or_test_case)
if not self.module_method_overrides or test_case_class.__name__ in self.module_method_overrides
)

def discover_tests_by_buckets():
Expand Down Expand Up @@ -153,23 +150,20 @@ def discover_tests_testing():
# For testing purposes only
return [self.test_path_or_test_case()]

discovered_tests = []
if isinstance(self.test_path_or_test_case, (TestCase, MetaTestCase)):
discovered_tests = discover_tests_testing()
elif self.bucket is not None:
discovered_tests = discover_tests_by_buckets()
else:
discovered_tests = discover_tests()

try:
if isinstance(self.test_path_or_test_case, (TestCase, MetaTestCase)):
discovered_tests = discover_tests_testing()
elif self.bucket is not None:
discovered_tests = discover_tests_by_buckets()
else:
discovered_tests = discover_tests()
for test in discovered_tests:
yield test
except test_discovery.DiscoveryError as exc:
for reporter in self.test_reporters:
reporter.test_discovery_failure(exc)
sys.exit(1)
test_case_count = len(discovered_tests)
test_method_count = sum(len(list(test_case.runnable_test_methods())) for test_case in discovered_tests)
for reporter in self.test_reporters:
reporter.test_counts(test_case_count, test_method_count)
return discovered_tests

def run(self):
"""Instantiate our found test case classes and run their test methods.
Expand Down Expand Up @@ -252,22 +246,14 @@ def list_suites(self):

def get_tests_for_suite(self, selected_suite_name):
"""Gets the test list for the suite"""
test_list = []
for test_instance in self.discover():
for test_method in test_instance.runnable_test_methods():
if not selected_suite_name or TestCase.in_suite(test_method, selected_suite_name):
test_list.append(test_method)
return test_list
yield test_method

def list_tests(self, selected_suite_name=None):
"""Lists all tests, optionally scoped to a single suite."""
test_list = self.get_tests_for_suite(selected_suite_name)
test_method_names = sorted([
self.get_test_method_name(test) for test in test_list
])
for test_method_name in test_method_names:
print(test_method_name)

return test_list
for test in self.get_tests_for_suite(selected_suite_name):
print(self.get_test_method_name(test))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this introduces a regression -- test discovery order is not deterministic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On inspection, it's clearly sorted.
Do you know how I induce unsortedness?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've confirmed that discovery on yelp-main is deterministic and sorted (matches LANG=C sort).
Shall I add some kind of assertion?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah but... how is that possible?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tracked it down. We use pkgutil to walk the modules, inspect to get the classes from modules, and dir to get methods from classes, and all three of these things sort their outputs.


# vim: set ts=4 sts=4 sw=4 et:
3 changes: 0 additions & 3 deletions testify/test_runner_json_replay.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ def run(self):
test_cases.add((result['method']['module'], result['method']['class'],))
test_methods.add((result['method']['module'], result['method']['class'], result['method']['name'],))

for reporter in self.test_reporters:
reporter.test_counts(len(test_cases), len(test_methods))

for result in self.results:
for reporter in self.test_reporters:
reporter.test_start(result)
Expand Down