Description
Currently, when an unittest.TestCase has two test methods with the same name, only the second one is run: the first one is silently ignored. In the past, the Python test suite had many bugs like that: see issue #60283. I just found a new bug today in test_sqlite3: issue #105557.
It would be nice to automatically detect when a test method is redefined. The problem is to avoid false alarms on method redefined on purpose: right now, I don't know if there are legit use cases like that.
Here is a prototype:
import inspect
import warnings
class MyDict(dict):
def __init__(self, class_name):
self.class_name = class_name
def __setitem__(self, name, value):
# TestLoader.testMethodPrefix = 'test'
if name.startswith('test'):
try:
old_value = self[name]
except KeyError:
pass
else:
if inspect.isfunction(old_value):
warnings.warn(f"BUG: {self.class_name}.{name}() method redefined", stacklevel=2)
dict.__setitem__(self, name, value)
class MyMetaClass(type):
@classmethod
def __prepare__(metacls, class_name, bases, **kwds):
return MyDict(class_name)
class TestCase(metaclass=MyMetaClass):
pass
class Tests(TestCase):
def __init__(self):
self.attr = 1
self.attr = 2
def test_bug(self): # first defintion
pass
def test_bug(self): # second definion
pass
class RealTests(Tests):
def test_bug(self): # implementation
print("run tests")
tests = RealTests()
Output:
poc.py:36: UserWarning: BUG: Tests.test_bug() method redefined
def test_bug(self): # second definion
It only emits a warning on the second Tests.test_bug() method definition. It doesn't emit a warning when RealTests redefines test_bug(): is it a legit use case to override an "abstract" test method of a "base" test case class? This case can also be detected if needed.