-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Unittest regression fixes #526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
021dc04
90f140a
5fe2291
094f3ef
5d349c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -418,23 +418,23 @@ def run_one(test_function): | |
|
|
||
| set_up_class() | ||
|
|
||
| if hasattr(o, "runTest"): | ||
| name = str(o) | ||
| run_one(o.runTest) | ||
| return | ||
|
|
||
| for name in dir(o): | ||
| if name.startswith("test"): | ||
| m = getattr(o, name) | ||
| if not callable(m): | ||
| continue | ||
| run_one(m) | ||
|
|
||
| if callable(o): | ||
| name = o.__name__ | ||
| run_one(o) | ||
|
|
||
| tear_down_class() | ||
| try: | ||
| if hasattr(o, "runTest"): | ||
| name = str(o) | ||
| run_one(o.runTest) | ||
| else: | ||
| for name in dir(o): | ||
| if name.startswith("test"): | ||
| m = getattr(o, name) | ||
| if not callable(m): | ||
| continue | ||
| run_one(m) | ||
|
|
||
| if callable(o): | ||
| name = o.__name__ | ||
| run_one(o) | ||
| finally: | ||
| tear_down_class() | ||
|
|
||
| return exceptions | ||
|
|
||
|
|
@@ -444,11 +444,11 @@ def _test_cases(mod): | |
| c = getattr(mod, tn) | ||
| if isinstance(c, object) and isinstance(c, type) and issubclass(c, TestCase): | ||
| yield c | ||
| elif tn.startswith("test_") and callable(c): | ||
| elif tn.startswith("test") and callable(c): | ||
| yield c | ||
|
|
||
|
|
||
| def run_module(runner, module, path, top): | ||
| def run_module(runner, module, *extra_paths): | ||
| if not module: | ||
| raise ValueError("Empty module name") | ||
|
|
||
|
|
@@ -457,13 +457,12 @@ def run_module(runner, module, path, top): | |
| sys.modules.update(__modules__) | ||
|
|
||
| sys_path_initial = sys.path[:] | ||
| # Add script dir and top dir to import path | ||
| sys.path.insert(0, str(path)) | ||
| if top: | ||
| sys.path.insert(1, top) | ||
| for path in (path for path in reversed(extra_paths) if path): | ||
| sys.path.insert(0, str(path)) | ||
|
|
||
| try: | ||
| suite = TestSuite(module) | ||
| m = __import__(module) if isinstance(module, str) else module | ||
| suite = TestSuite(m.__name__) | ||
| for c in _test_cases(m): | ||
| suite.addTest(c) | ||
| result = runner.run(suite) | ||
|
|
@@ -481,7 +480,16 @@ def discover(runner: TestRunner): | |
| return discover(runner=runner) | ||
|
|
||
|
|
||
| def main(module="__main__", testRunner=None): | ||
| def split_path(path): | ||
| path = path.replace("\\", "/") | ||
| if "/" in path: | ||
| return path.rsplit("/", 1) | ||
| else: | ||
| return ".", path | ||
|
|
||
|
|
||
| def main(module="__main__", **kwargs): | ||
| testRunner = kwargs.get("testRunner", None) | ||
| if testRunner: | ||
| if isinstance(testRunner, type): | ||
| runner = testRunner() | ||
|
|
@@ -490,29 +498,34 @@ def main(module="__main__", testRunner=None): | |
| else: | ||
| runner = TestRunner() | ||
|
|
||
| if len(sys.argv) <= 1: | ||
| result = discover(runner) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Do you mean this original? This was intended to catch the It's true I don't know if there's ever a case where
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes exactly. But without the check it would be unconditionally indexing |
||
| elif sys.argv[0].split(".")[0] == "unittest" and sys.argv[1] == "discover": | ||
| result = discover(runner) | ||
| if module is not None: | ||
| result = run_module(runner, module) | ||
| else: | ||
| for test_spec in sys.argv[1:]: | ||
| try: | ||
| uos.stat(test_spec) | ||
| # test_spec is a local file, run it directly | ||
| if "/" in test_spec: | ||
| path, fname = test_spec.rsplit("/", 1) | ||
| else: | ||
| path, fname = ".", test_spec | ||
| modname = fname.rsplit(".", 1)[0] | ||
| result = run_module(runner, modname, path, None) | ||
|
|
||
| except OSError: | ||
| # Not a file, treat as import name | ||
| result = run_module(runner, test_spec, ".", None) | ||
| argn = len(sys.argv) | ||
| # See https://docs.python.org/3/library/unittest.html#test-discovery: | ||
| # python -m unittest is the equivalent of python -m unittest discover. | ||
| if not argn or ( | ||
| sys.argv[0].split(".")[0] == "unittest" | ||
| and (argn == 1 or (argn >= 1 and sys.argv[1] == "discover")) | ||
| ): | ||
| result = discover(runner) | ||
| # Remaining arguments should be test specifiers. | ||
| else: | ||
| for test_spec in sys.argv[1:]: | ||
| try: | ||
| uos.stat(test_spec) | ||
| # test_spec is a local file, run it directly | ||
| path, fname = split_path(test_spec) | ||
| modname = fname.rsplit(".", 1)[0] | ||
| result = run_module(runner, modname, path) | ||
|
|
||
| except OSError: | ||
| # Not a file, treat as import name | ||
| result = run_module(runner, test_spec, ".") | ||
|
|
||
| # Terminate with non zero return code in case of failures | ||
| sys.exit(result.failuresNum or result.errorsNum) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| main(None) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for breaking some tests with this change... I don't remember clearly now but I think I found some existing test scripts in the repo where there were testFoo functions being run that were not intended to be unittest functions, so thought the
_made more sense. I believe this is non-standard functionality that cpython doesn't support anyway (finding & running bare test* functions)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so yes, at least I didn't find anything which does that. I'd personally refrain from doing that because it's non-standard, and because if you have a file like that then decide it runs under CPython as well you might think its tests are all fine but they are just not being ran. CPython does support a single
runTestfunction though likeBut anyway
testis the standard prefix; e.g.By default these are the method names beginning with testandtestMethodPrefix = 'test'inunittest/loader.py.