gh-62432: unittest runner: Exit code 5 if no tests were run (#102051)

As discussed in https://discuss.python.org/t/unittest-fail-if-zero-tests-were-discovered/21498/7

It is common for test runner misconfiguration to fail to find any tests,
This should be an error.

Fixes: #62432
This commit is contained in:
Stefano Rivera 2023-04-26 18:28:46 -07:00 committed by GitHub
parent dc3f97549a
commit 76632b836c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 64 additions and 22 deletions

View file

@ -71,15 +71,22 @@ class Test_TestProgram(unittest.TestCase):
def testUnexpectedSuccess(self):
pass
class FooBarLoader(unittest.TestLoader):
"""Test loader that returns a suite containing FooBar."""
class Empty(unittest.TestCase):
pass
class TestLoader(unittest.TestLoader):
"""Test loader that returns a suite containing the supplied testcase."""
def __init__(self, testcase):
self.testcase = testcase
def loadTestsFromModule(self, module):
return self.suiteClass(
[self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
[self.loadTestsFromTestCase(self.testcase)])
def loadTestsFromNames(self, names, module):
return self.suiteClass(
[self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
[self.loadTestsFromTestCase(self.testcase)])
def test_defaultTest_with_string(self):
class FakeRunner(object):
@ -92,7 +99,7 @@ class Test_TestProgram(unittest.TestCase):
runner = FakeRunner()
program = unittest.TestProgram(testRunner=runner, exit=False,
defaultTest='test.test_unittest',
testLoader=self.FooBarLoader())
testLoader=self.TestLoader(self.FooBar))
sys.argv = old_argv
self.assertEqual(('test.test_unittest',), program.testNames)
@ -108,7 +115,7 @@ class Test_TestProgram(unittest.TestCase):
program = unittest.TestProgram(
testRunner=runner, exit=False,
defaultTest=['test.test_unittest', 'test.test_unittest2'],
testLoader=self.FooBarLoader())
testLoader=self.TestLoader(self.FooBar))
sys.argv = old_argv
self.assertEqual(['test.test_unittest', 'test.test_unittest2'],
program.testNames)
@ -118,7 +125,7 @@ class Test_TestProgram(unittest.TestCase):
program = unittest.main(exit=False,
argv=["foobar"],
testRunner=unittest.TextTestRunner(stream=stream),
testLoader=self.FooBarLoader())
testLoader=self.TestLoader(self.FooBar))
self.assertTrue(hasattr(program, 'result'))
out = stream.getvalue()
self.assertIn('\nFAIL: testFail ', out)
@ -130,13 +137,13 @@ class Test_TestProgram(unittest.TestCase):
def test_Exit(self):
stream = BufferedWriter()
self.assertRaises(
SystemExit,
unittest.main,
argv=["foobar"],
testRunner=unittest.TextTestRunner(stream=stream),
exit=True,
testLoader=self.FooBarLoader())
with self.assertRaises(SystemExit) as cm:
unittest.main(
argv=["foobar"],
testRunner=unittest.TextTestRunner(stream=stream),
exit=True,
testLoader=self.TestLoader(self.FooBar))
self.assertEqual(cm.exception.code, 1)
out = stream.getvalue()
self.assertIn('\nFAIL: testFail ', out)
self.assertIn('\nERROR: testError ', out)
@ -147,12 +154,11 @@ class Test_TestProgram(unittest.TestCase):
def test_ExitAsDefault(self):
stream = BufferedWriter()
self.assertRaises(
SystemExit,
unittest.main,
argv=["foobar"],
testRunner=unittest.TextTestRunner(stream=stream),
testLoader=self.FooBarLoader())
with self.assertRaises(SystemExit):
unittest.main(
argv=["foobar"],
testRunner=unittest.TextTestRunner(stream=stream),
testLoader=self.TestLoader(self.FooBar))
out = stream.getvalue()
self.assertIn('\nFAIL: testFail ', out)
self.assertIn('\nERROR: testError ', out)
@ -161,6 +167,17 @@ class Test_TestProgram(unittest.TestCase):
'expected failures=1, unexpected successes=1)\n')
self.assertTrue(out.endswith(expected))
def test_ExitEmptySuite(self):
stream = BufferedWriter()
with self.assertRaises(SystemExit) as cm:
unittest.main(
argv=["empty"],
testRunner=unittest.TextTestRunner(stream=stream),
testLoader=self.TestLoader(self.Empty))
self.assertEqual(cm.exception.code, 5)
out = stream.getvalue()
self.assertIn('\nNO TESTS RAN\n', out)
class InitialisableProgram(unittest.TestProgram):
exit = False