-
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
Conversation
7f36020 to
705f32f
Compare
|
Thanks for the updates - when I originally tried to run "all tests in the repo" with the discover updates there were so many failures from a mixture of:
I'm curious about the first commit here:
This usage seems to work fine for me as-is on current master? Can you suggest a reproduction of the issue you ran into? |
| 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): |
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 believe this is non-standard functionality that cpython doesn't support anyway (finding & running bare test* functions)?
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 runTest function though like
class Test(unittest.TestCase):
@staticmethod
def runTest():
test = unittest.TestCase()
test.assertEqual(1, 1)
But anyway test is the standard prefix; e.g. By default these are the method names beginning with test and testMethodPrefix = 'test' in unittest/loader.py.
unix-ffi/unittest/unittest.py
Outdated
| result = discover(runner) | ||
| # If there's one argument assume it's the path to the script which called main(), so run its tests. | ||
| elif argn == 1: | ||
| result = run_module(runner, module, split_path(sys.argv[0])[0], 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.
split_path(sys.argv[0])
This is to split out just the filename isn't it... I would think this will fail if you're running a unittest from a different folder?
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.
Yeah that's basically os.path.dirname . Not sure why that would fail, the point of the path argument is to add the script directory to sys.path right? So python /path/to/test.py is going to add path/to. I just realize this is not actually needed though, the directory of the executing script gets added to sys.path anyway. Moreover, as the comment says this is an assumption but thinking about it: this is just wrong and I'm going to remove it. If anything argv[0] could be used as prog name for argparse but that's it.
The output from your test actually shows the problem: it runs not just test_unittest, but both test_unittest and test_unittest_isolation, because it's running test discovery in the current directory. E.g. running in the unittest directory and it will simply ignore the argument to Btw any idea why Also: ping for my other comment |
Fix regression introduced by a7b2f63 which broke the typical case of running a test script which has if __name__ == "__main__": unittest.main()
Fix regression introduced by 9d9ca3d.
CPython's unittest.main() function uses a different argument order than what we have now, so to avoid future problems with unclear error messages should we add arguments in the future, force callers to specify exact arguments.
705f32f to
094f3ef
Compare
|
I went over the code again and fixed some things:
Note the code still has the equivalent of |
Ah I see now. That'll be why I hadn't noticed the bug - at first glance it looks like it's still working. But it's not doing the right thing certainly, and pulls in the dependency when it wasn't intended to. Nice fix, thanks! |
That I'm not sure about, didn't get a chance to investigate when I ran that this morning. |
| runner = TestRunner() | ||
|
|
||
| if len(sys.argv) <= 1: | ||
| result = discover(runner) |
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.
Note the code still has the equivalent of
if len(sys.argv) == 0: discover()because the original had that. but I'm not sure what it would mean for sys.argv to be empty?
Do you mean this original? This was intended to catch the len==1 mostly, main case of this is micropython -m unittest where sys.argv == ['unittest'].
It's true I don't know if there's ever a case where len(sys.argv) == 0 unless you're manipulating sys.argv manually in a wrapper script, in which case all bets are off really. Not sure if I had a specific reason to make this <= 1 rather than just == 1 other than maybe not wanting to leave an undefined case statement.
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.
Do you mean this original?
Yes exactly.
But without the check it would be unconditionally indexing sys.argv which is also not very nice so I'll just leave it as-is.
These must be class methods decorated, and tearDownClass must be called after runTest() as well.
|
Thanks @stinos . I think all of this should be addressed by #527 (comment) Please let me know if not. |
|
Should be fixed in 796a598 |
I finally came around to getting my micropython-lib fork in sync, turns out it broke all my tests :) Strange no-one noticed this.