-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
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
unittest: deprecate test methods returning non-None values #85494
Comments
The following testcase will always be marked as passed: from unittest import TestCase
class BuggyTestCase(TestCase):
def test_generator(self):
self.assertTrue(False)
yield None It happened to us that someone accidentally made the test method a generator function. That error was caught very late, because it always appears to have executed correctly. Maybe an additional check can be introduced in the unittest module, to check if a test_ method was executed correctly? |
Line 548 in 8e836bb
import unittest
from unittest import TestCase
class BuggyTestCase(TestCase):
def _callTestMethod(self, method):
import inspect
if inspect.isgeneratorfunction(method):
list(method())
else:
method()
def test_generator(self):
self.assertTrue(False)
yield None
if __name__ == "__main__":
unittest.main() python3.8 test_foo.py Traceback (most recent call last):
File "test_foo.py", line 10, in _callTestMethod
list(method())
File "test_foo.py", line 15, in test_generator
self.assertTrue(False)
AssertionError: False is not true Ran 1 test in 0.000s FAILED (failures=1) |
This is a duplicate of bpo-15551 and as per discussion in the thread my approach is incoherent with design of unittest to execute generators. I propose closing this as duplicate with same resolution as not fixed unless there is a change required here. |
I would raser raise error if the test method returns something suspicious, like generator or coroutine. Or maybe if it returns anything except None. |
I would also strongly vote for raising an error if the test method is a generator - not even silently turn it into a list. It would be straight forward to implement various checks (like the ones you mentioned for generators, coroutines, ...) - and they will absolutely help to prevent unintended errors, especially by more junior developers. |
In the same vein as Serhiy's suggestion, I would like to see unittest raise a DeprecationWarning when a test method returns anything other than |
The current behavior is not a bug as it follows documented behavior. In the absence of any use for returning values from test functions, I agree that we should do the simple thing and raise ValueError (I checked and did not find anything like a UnittestError.) That would add minimal time to testing. |
It is also a good idea for linters to catch such kind of errors. It will help users of older Python versions. We cannot raise error without deprecation period or add warnings in old versions because it potentially can break existing code, e.g.: def test_ham(self, arg='ham'):
...
def test_spam(self):
res = test_ham('spam')
self.assertTrue(res) |
Thanks for reporting, Alexander, and Andrei for the patch! ✨ 🍰 ✨ |
I will add the test in the next 1-2 days, I should have asked if it's needed in this case.. |
Every new feature should be documented and covered by tests (unless it is very trivial or it is very difficult to write a test for it). |
It looks like since #71935 got merged, |
That test does have a yield statement in it, and does cause the deprecation warning to fire off. I'm looking into it.. |
Would rewriting the test so that it doesn't yield be the right fix?
to
|
Yes, it seems like this deprecation detected a broken test that wasn't running. If I add a OK (with last line of test being just It seems to me it should be fixed in some way although I don't know if Ryan's suggestion will do or not as I haven't looked at asyncio tests before.. |
The test was refactored in this commit: 658103f the refactoring moved yield statement from inner func into the test. That was 8 years ago so it hasn't worked since then, and since asyncio changed a lot, I wonder if the test is still valid? Ryan, do you want to open a new issue for fixing / removing the test? |
Sure, I'll open a new issue. |
The new issue for the failing test is bpo-44968 |
There are few deprecation warnings in other tests : 0:00:05 load avg: 3.20 [ 52/428] test_code passed 0:00:12 load avg: 3.74 [110/428] test_capi passed 0:00:13 load avg: 3.74 [114/428] test_distutils passed |
Karthikeyan: I was looking into them yesterday, and:
but I haven't worked with C tests before and it looks like some other C api tests also return non-null and not None values, but they didn't trigger the deprecation when running a test PR I made yesterday here: https://github.com/python/cpython/pull/27869/checks?check_run_id=3387700689 |
I should just add that none of the these tests are actually a problem, i.e. they all do run properly and not running duplicate times (except that I'm not sure about the 2 distutils tests, but that shouldn't matter much as distutils is deprecated and up for removal). |
Deprecation warnings are not on by default in tests. You can pass -Wall while running tests to turn on all warnings. ./python -Wall -m test test_capi == Tests result: SUCCESS == 1 test OK. Total duration: 5.2 sec |
This can be re-closed. Deprecation warnings raised by the test suite are being fixed in BPO-44980 which already has an open pull request. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: