[Python-checkins] [3.9] bpo-45229: Remove test_main in many tests (GH-28405) (GH-28456)

serhiy-storchaka webhook-mailer at python.org
Mon Sep 20 02:35:00 EDT 2021


https://github.com/python/cpython/commit/5822ab672a1d26ff1837103c1ed8e4c3c2a42b87
commit: 5822ab672a1d26ff1837103c1ed8e4c3c2a42b87
branch: 3.9
author: Serhiy Storchaka <storchaka at gmail.com>
committer: serhiy-storchaka <storchaka at gmail.com>
date: 2021-09-20T09:34:52+03:00
summary:

[3.9] bpo-45229: Remove test_main in many tests (GH-28405) (GH-28456)

Instead of explicitly enumerate test classes for run_unittest()
use the unittest ability to discover tests. This also makes these
tests discoverable and runnable with unittest.

load_tests() can be used for dynamic generating tests and adding
doctests. setUpModule(), tearDownModule() and addModuleCleanup()
can be used for running code before and after all module tests..
(cherry picked from commit 40348acc180580371d25f75f46b27048e35f2435)

files:
M Lib/lib2to3/tests/data/py2_test_grammar.py
M Lib/lib2to3/tests/data/py3_test_grammar.py
M Lib/test/support/__init__.py
M Lib/test/test_argparse.py
M Lib/test/test_bdb.py
M Lib/test/test_bigaddrspace.py
M Lib/test/test_bigmem.py
M Lib/test/test_bool.py
M Lib/test/test_bz2.py
M Lib/test/test_c_locale_coercion.py
M Lib/test/test_cmd_line.py
M Lib/test/test_cmd_line_script.py
M Lib/test/test_complex.py
M Lib/test/test_concurrent_futures.py
M Lib/test/test_descr.py
M Lib/test/test_devpoll.py
M Lib/test/test_difflib.py
M Lib/test/test_distutils.py
M Lib/test/test_dtrace.py
M Lib/test/test_fcntl.py
M Lib/test/test_filecmp.py
M Lib/test/test_fileio.py
M Lib/test/test_ftplib.py
M Lib/test/test_gc.py
M Lib/test/test_global.py
M Lib/test/test_gzip.py
M Lib/test/test_httpservers.py
M Lib/test/test_importlib/test_locks.py
M Lib/test/test_importlib/test_threaded_import.py
M Lib/test/test_inspect.py
M Lib/test/test_iter.py
M Lib/test/test_logging.py
M Lib/test/test_lzma.py
M Lib/test/test_mailbox.py
M Lib/test/test_multibytecodec.py
M Lib/test/test_optparse.py
M Lib/test/test_ossaudiodev.py
M Lib/test/test_pipes.py
M Lib/test/test_pkgutil.py
M Lib/test/test_poll.py
M Lib/test/test_poplib.py
M Lib/test/test_posix.py
M Lib/test/test_profile.py
M Lib/test/test_pydoc.py
M Lib/test/test_resource.py
M Lib/test/test_sax.py
M Lib/test/test_selectors.py
M Lib/test/test_ssl.py
M Lib/test/test_support.py
M Lib/test/test_tcl.py
M Lib/test/test_threadsignals.py
M Lib/test/test_timeout.py
M Lib/test/test_tracemalloc.py
M Lib/test/test_unicode_file.py
M Lib/test/test_unicode_file_functions.py
M Lib/test/test_unittest.py
M Lib/test/test_urllib2_localnet.py
M Lib/test/test_winreg.py
M Lib/test/test_xmlrpc.py
M Lib/test/test_xmlrpc_net.py
M Lib/test/test_zipimport.py

diff --git a/Lib/lib2to3/tests/data/py2_test_grammar.py b/Lib/lib2to3/tests/data/py2_test_grammar.py
index 866316173a5b3..f9e4ea1374f90 100644
--- a/Lib/lib2to3/tests/data/py2_test_grammar.py
+++ b/Lib/lib2to3/tests/data/py2_test_grammar.py
@@ -8,7 +8,7 @@
 # regression test, the filterwarnings() call has been added to
 # regrtest.py.
 
-from test.test_support import run_unittest, check_syntax_error
+from test.test_support import check_syntax_error
 import unittest
 import sys
 # testing import *
@@ -967,8 +967,5 @@ def _checkeval(msg, ret):
         self.assertEqual((6 < 4 if 0 else 2), 2)
 
 
-def test_main():
-    run_unittest(TokenTests, GrammarTests)
-
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/lib2to3/tests/data/py3_test_grammar.py b/Lib/lib2to3/tests/data/py3_test_grammar.py
index e1eee524874f8..a4a3f7eac0dde 100644
--- a/Lib/lib2to3/tests/data/py3_test_grammar.py
+++ b/Lib/lib2to3/tests/data/py3_test_grammar.py
@@ -8,7 +8,7 @@
 # regression test, the filterwarnings() call has been added to
 # regrtest.py.
 
-from test.support import run_unittest, check_syntax_error
+from test.support import check_syntax_error
 import unittest
 import sys
 # testing import *
@@ -952,8 +952,5 @@ def _checkeval(msg, ret):
         self.assertEqual((6 < 4 if 0 else 2), 2)
 
 
-def test_main():
-    run_unittest(TokenTests, GrammarTests)
-
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 7e5a29b18de39..51af6f37d9bce 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -1525,9 +1525,8 @@ def check_sizeof(test, o, size):
 # Decorator for running a function in a different locale, correctly resetting
 # it afterwards.
 
+ at contextlib.contextmanager
 def run_with_locale(catstr, *locales):
-    def decorator(func):
-        def inner(*args, **kwds):
             try:
                 import locale
                 category = getattr(locale, catstr)
@@ -1546,16 +1545,11 @@ def inner(*args, **kwds):
                     except:
                         pass
 
-            # now run the function, resetting the locale on exceptions
             try:
-                return func(*args, **kwds)
+                yield
             finally:
                 if locale and orig_locale:
                     locale.setlocale(category, orig_locale)
-        inner.__name__ = func.__name__
-        inner.__doc__ = func.__doc__
-        return inner
-    return decorator
 
 #=======================================================================
 # Decorator for running a function in a specific timezone, correctly
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index ab5f35f0beea5..82c1f6c60f828 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -5394,13 +5394,11 @@ def test_exit_on_error_with_bad_args(self):
             self.parser.parse_args('--integers a'.split())
 
 
-def test_main():
-    support.run_unittest(__name__)
+def tearDownModule():
     # Remove global references to avoid looking like we have refleaks.
     RFile.seen = {}
     WFile.seen = set()
 
 
-
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py
index ae16880567882..405f741e36b04 100644
--- a/Lib/test/test_bdb.py
+++ b/Lib/test/test_bdb.py
@@ -1149,13 +1149,6 @@ def main():
             with TracerRun(self) as tracer:
                 tracer.runcall(tfunc_import)
 
-def test_main():
-    test.support.run_unittest(
-        StateTestCase,
-        RunTestCase,
-        BreakpointTestCase,
-        IssuesTestCase,
-    )
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_bigaddrspace.py b/Lib/test/test_bigaddrspace.py
index aa1f8ca75a981..50272e99607fd 100644
--- a/Lib/test/test_bigaddrspace.py
+++ b/Lib/test/test_bigaddrspace.py
@@ -92,10 +92,7 @@ def test_repeat(self):
             x = None
 
 
-def test_main():
-    support.run_unittest(BytesTest, StrTest)
-
 if __name__ == '__main__':
     if len(sys.argv) > 1:
         support.set_memlimit(sys.argv[1])
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_bigmem.py b/Lib/test/test_bigmem.py
index 6a244dd8c9480..859f1539e20b8 100644
--- a/Lib/test/test_bigmem.py
+++ b/Lib/test/test_bigmem.py
@@ -1247,11 +1247,8 @@ def test_sort(self, size):
         self.assertEqual(l[:10], [1] * 10)
         self.assertEqual(l[-10:], [5] * 10)
 
-def test_main():
-    support.run_unittest(StrTest, BytesTest, BytearrayTest,
-        TupleTest, ListTest)
 
 if __name__ == '__main__':
     if len(sys.argv) > 1:
         support.set_memlimit(sys.argv[1])
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py
index 909a59a9d2af6..5550f74c084cb 100644
--- a/Lib/test/test_bool.py
+++ b/Lib/test/test_bool.py
@@ -362,8 +362,6 @@ def test_real_and_imag(self):
         self.assertIs(type(False.real), int)
         self.assertIs(type(False.imag), int)
 
-def test_main():
-    support.run_unittest(BoolTest)
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py
index c84f70ebb094a..fe12816ff0626 100644
--- a/Lib/test/test_bz2.py
+++ b/Lib/test/test_bz2.py
@@ -1002,15 +1002,9 @@ def test_newline(self):
             self.assertEqual(f.readlines(), [text])
 
 
-def test_main():
-    support.run_unittest(
-        BZ2FileTest,
-        BZ2CompressorTest,
-        BZ2DecompressorTest,
-        CompressDecompressTest,
-        OpenTest,
-    )
+def tearDownModule():
     support.reap_children()
 
+
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py
index fcc85992345db..71f934756e26a 100644
--- a/Lib/test/test_c_locale_coercion.py
+++ b/Lib/test/test_c_locale_coercion.py
@@ -427,12 +427,9 @@ def test_PYTHONCOERCECLOCALE_set_to_one(self):
         self.assertEqual(cmd.stdout.rstrip(), loc)
 
 
-def test_main():
-    support.run_unittest(
-        LocaleConfigurationTests,
-        LocaleCoercionTests
-    )
+def tearDownModule():
     support.reap_children()
 
+
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index a3560b4b1fd9b..712d861c4d5a3 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -841,9 +841,9 @@ def test_sys_flags_not_set(self):
         )
 
 
-def test_main():
-    support.run_unittest(CmdLineTest, IgnoreEnvironmentTest)
+def tearDownModule():
     support.reap_children()
 
+
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py
index 7a3707d0f112f..7cb1370c981b0 100644
--- a/Lib/test/test_cmd_line_script.py
+++ b/Lib/test/test_cmd_line_script.py
@@ -737,9 +737,9 @@ def test_nonexisting_script(self):
         self.assertNotEqual(proc.returncode, 0)
 
 
-def test_main():
-    support.run_unittest(CmdLineTest)
+def tearDownModule():
     support.reap_children()
 
+
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py
index 0db9be5190da4..7122300522bff 100644
--- a/Lib/test/test_complex.py
+++ b/Lib/test/test_complex.py
@@ -751,8 +751,6 @@ def test_format(self):
         self.assertEqual(format(complex(INF, 1), 'F'), 'INF+1.000000j')
         self.assertEqual(format(complex(INF, -1), 'F'), 'INF-1.000000j')
 
-def test_main():
-    support.run_unittest(ComplexTest)
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py
index ad64f4bdb5322..8545c26d95005 100644
--- a/Lib/test/test_concurrent_futures.py
+++ b/Lib/test/test_concurrent_futures.py
@@ -1500,16 +1500,10 @@ def test_multiple_set_exception(self):
         self.assertEqual(f.exception(), e)
 
 
-_threads_key = None
-
 def setUpModule():
-    global _threads_key
-    _threads_key = support.threading_setup()
-
-
-def tearDownModule():
-    support.threading_cleanup(*_threads_key)
-    multiprocessing.util._cleanup_tests()
+    unittest.addModuleCleanup(multiprocessing.util._cleanup_tests)
+    thread_info = support.threading_setup()
+    unittest.addModuleCleanup(support.threading_cleanup, *thread_info)
 
 
 if __name__ == "__main__":
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index c7a191bccd69c..2fa68b201172f 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -4945,8 +4945,11 @@ def test_repr(self):
             self.assertIn('{!r}: {!r}'.format(k, v), r)
 
 
-class PTypesLongInitTest(unittest.TestCase):
+class AAAPTypesLongInitTest(unittest.TestCase):
     # This is in its own TestCase so that it can be run before any other tests.
+    # (Hence the 'AAA' in the test class name: to make it the first
+    # item in a list sorted by name, like
+    # unittest.TestLoader.getTestCaseNames() does.)
     def test_pytype_long_ready(self):
         # Testing SF bug 551412 ...
 
@@ -5684,12 +5687,5 @@ class A(metaclass=M):
             pass
 
 
-def test_main():
-    # Run all local test cases, with PTypesLongInitTest first.
-    support.run_unittest(PTypesLongInitTest, OperatorsTest,
-                         ClassPropertiesAndMethods, DictProxyTests,
-                         MiscTests, PicklingTests, SharedKeyTests,
-                         MroTest)
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_devpoll.py b/Lib/test/test_devpoll.py
index 110c006862737..85e0accb611b1 100644
--- a/Lib/test/test_devpoll.py
+++ b/Lib/test/test_devpoll.py
@@ -6,7 +6,7 @@
 import random
 import select
 import unittest
-from test.support import run_unittest, cpython_only
+from test.support import cpython_only
 
 if not hasattr(select, 'devpoll') :
     raise unittest.SkipTest('test works only on Solaris OS family')
@@ -138,8 +138,5 @@ def test_events_mask_overflow_c_limits(self):
         self.assertRaises(OverflowError, pollster.modify, 1, USHRT_MAX + 1)
 
 
-def test_main():
-    run_unittest(DevPollTests)
-
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py
index 42ac1fdcd81cd..d9399364f6aad 100644
--- a/Lib/test/test_difflib.py
+++ b/Lib/test/test_difflib.py
@@ -1,5 +1,5 @@
 import difflib
-from test.support import run_unittest, findfile
+from test.support import findfile
 import unittest
 import doctest
 import sys
@@ -547,12 +547,14 @@ def test_longest_match_with_popular_chars(self):
         self.assertFalse(self.longer_match_exists(a, b, match.size))
 
 
-def test_main():
+def setUpModule():
     difflib.HtmlDiff._default_prefix = 0
-    Doctests = doctest.DocTestSuite(difflib)
-    run_unittest(
-        TestWithAscii, TestAutojunk, TestSFpatches, TestSFbugs,
-        TestOutputFormat, TestBytes, TestJunkAPIs, TestFindLongest, Doctests)
+
+
+def load_tests(loader, tests, pattern):
+    tests.addTest(doctest.DocTestSuite(difflib))
+    return tests
+
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_distutils.py b/Lib/test/test_distutils.py
index a37f11791754d..790d39c6d35ae 100644
--- a/Lib/test/test_distutils.py
+++ b/Lib/test/test_distutils.py
@@ -9,16 +9,14 @@
 import test.support
 
 
-def test_main():
-    # used by regrtest
-    test.support.run_unittest(distutils.tests.test_suite())
-    test.support.reap_children()
-
-
 def load_tests(*_):
     # used by unittest
     return distutils.tests.test_suite()
 
 
+def tearDownModule():
+    test.support.reap_children()
+
+
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_dtrace.py b/Lib/test/test_dtrace.py
index 8612e276d7658..1db73cc2d2220 100644
--- a/Lib/test/test_dtrace.py
+++ b/Lib/test/test_dtrace.py
@@ -6,7 +6,7 @@
 import types
 import unittest
 
-from test.support import findfile, run_unittest
+from test.support import findfile
 
 
 def abspath(filename):
@@ -97,7 +97,7 @@ class SystemTapBackend(TraceBackend):
     COMMAND = ["stap", "-g"]
 
 
-class TraceTests(unittest.TestCase):
+class TraceTests:
     # unittest.TestCase options
     maxDiff = None
 
@@ -149,30 +149,25 @@ def test_line(self):
         self.run_case("line")
 
 
-class DTraceNormalTests(TraceTests):
+class DTraceNormalTests(TraceTests, unittest.TestCase):
     backend = DTraceBackend()
     optimize_python = 0
 
 
-class DTraceOptimizedTests(TraceTests):
+class DTraceOptimizedTests(TraceTests, unittest.TestCase):
     backend = DTraceBackend()
     optimize_python = 2
 
 
-class SystemTapNormalTests(TraceTests):
+class SystemTapNormalTests(TraceTests, unittest.TestCase):
     backend = SystemTapBackend()
     optimize_python = 0
 
 
-class SystemTapOptimizedTests(TraceTests):
+class SystemTapOptimizedTests(TraceTests, unittest.TestCase):
     backend = SystemTapBackend()
     optimize_python = 2
 
 
-def test_main():
-    run_unittest(DTraceNormalTests, DTraceOptimizedTests, SystemTapNormalTests,
-                 SystemTapOptimizedTests)
-
-
 if __name__ == '__main__':
     test_main()
diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py
index 9ab68c67241f4..2a3209eb7db20 100644
--- a/Lib/test/test_fcntl.py
+++ b/Lib/test/test_fcntl.py
@@ -6,7 +6,7 @@
 import sys
 import unittest
 from multiprocessing import Process
-from test.support import (verbose, TESTFN, unlink, run_unittest, import_module,
+from test.support import (verbose, TESTFN, unlink, import_module,
                           cpython_only)
 
 # Skip test if no fcntl module.
@@ -188,8 +188,6 @@ def test_fcntl_f_getpath(self):
         res = fcntl.fcntl(self.f.fileno(), fcntl.F_GETPATH, bytes(len(expected)))
         self.assertEqual(expected, res)
 
-def test_main():
-    run_unittest(TestFcntl)
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_filecmp.py b/Lib/test/test_filecmp.py
index b5b24a24c8dde..f6228cc4133ac 100644
--- a/Lib/test/test_filecmp.py
+++ b/Lib/test/test_filecmp.py
@@ -210,8 +210,5 @@ def _assert_report(self, dircmp_report, expected_report_lines):
             self.assertEqual(report_lines, expected_report_lines)
 
 
-def test_main():
-    support.run_unittest(FileCompareTestCase, DirCompareTestCase)
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py
index 77c7f69a03e1d..2671d6a174e87 100644
--- a/Lib/test/test_fileio.py
+++ b/Lib/test/test_fileio.py
@@ -9,7 +9,7 @@
 from weakref import proxy
 from functools import wraps
 
-from test.support import (TESTFN, TESTFN_UNICODE, check_warnings, run_unittest,
+from test.support import (TESTFN, TESTFN_UNICODE, check_warnings,
                           make_bad_fd, cpython_only, swap_attr, gc_collect)
 from collections import UserList
 
@@ -605,15 +605,12 @@ def test_open_code(self):
             self.assertNotEqual(w.warnings, [])
 
 
-def test_main():
+def tearDownModule():
     # Historically, these tests have been sloppy about removing TESTFN.
     # So get rid of it no matter what.
-    try:
-        run_unittest(CAutoFileTests, PyAutoFileTests,
-                     COtherFileTests, PyOtherFileTests)
-    finally:
-        if os.path.exists(TESTFN):
-            os.unlink(TESTFN)
+    if os.path.exists(TESTFN):
+        os.unlink(TESTFN)
+
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py
index b76287bfe1c27..6f8f977b3950d 100644
--- a/Lib/test/test_ftplib.py
+++ b/Lib/test/test_ftplib.py
@@ -12,6 +12,7 @@
 import os
 import threading
 import time
+import unittest
 try:
     import ssl
 except ImportError:
@@ -1136,18 +1137,10 @@ def test__all__(self):
         support.check__all__(self, ftplib, blacklist=blacklist)
 
 
-def test_main():
-    tests = [TestFTPClass, TestTimeouts,
-             TestIPv6Environment,
-             TestTLS_FTPClassMixin, TestTLS_FTPClass,
-             MiscTestCase]
-
+def setUpModule():
     thread_info = support.threading_setup()
-    try:
-        support.run_unittest(*tests)
-    finally:
-        support.threading_cleanup(*thread_info)
+    unittest.addModuleCleanup(support.threading_cleanup, *thread_info)
 
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py
index 59cff20e6a7e7..3313804703f7e 100644
--- a/Lib/test/test_gc.py
+++ b/Lib/test/test_gc.py
@@ -1,6 +1,6 @@
 import unittest
 import unittest.mock
-from test.support import (verbose, refcount_test, run_unittest,
+from test.support import (verbose, refcount_test,
                           cpython_only, start_threads,
                           temp_dir, TESTFN, unlink,
                           import_module)
@@ -1388,30 +1388,27 @@ def search_func(encoding):
         assert_python_ok("-c", code)
 
 
-def test_main():
+def setUpModule():
+    global enabled, debug
     enabled = gc.isenabled()
     gc.disable()
     assert not gc.isenabled()
     debug = gc.get_debug()
     gc.set_debug(debug & ~gc.DEBUG_LEAK) # this test is supposed to leak
+    gc.collect() # Delete 2nd generation garbage
+
+
+def tearDownModule():
+    gc.set_debug(debug)
+    # test gc.enable() even if GC is disabled by default
+    if verbose:
+        print("restoring automatic collection")
+    # make sure to always test gc.enable()
+    gc.enable()
+    assert gc.isenabled()
+    if not enabled:
+        gc.disable()
 
-    try:
-        gc.collect() # Delete 2nd generation garbage
-        run_unittest(
-            GCTests,
-            GCCallbackTests,
-            GCTogglingTests,
-            PythonFinalizationTests)
-    finally:
-        gc.set_debug(debug)
-        # test gc.enable() even if GC is disabled by default
-        if verbose:
-            print("restoring automatic collection")
-        # make sure to always test gc.enable()
-        gc.enable()
-        assert gc.isenabled()
-        if not enabled:
-            gc.disable()
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_global.py b/Lib/test/test_global.py
index 8159602be98ee..e60f00206bf4c 100644
--- a/Lib/test/test_global.py
+++ b/Lib/test/test_global.py
@@ -1,6 +1,6 @@
 """Verify that warnings are issued for global statements following use."""
 
-from test.support import run_unittest, check_syntax_error, check_warnings
+from test.support import check_syntax_error, check_warnings
 import unittest
 import warnings
 
@@ -52,10 +52,12 @@ def test4(self):
         compile(prog_text_4, "<test string>", "exec")
 
 
-def test_main():
-    with warnings.catch_warnings():
-        warnings.filterwarnings("error", module="<test string>")
-        run_unittest(GlobalTests)
+def setUpModule():
+    cm = warnings.catch_warnings()
+    cm.__enter__()
+    unittest.addModuleCleanup(cm.__exit__, None, None, None)
+    warnings.filterwarnings("error", module="<test string>")
+
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py
index 1af23c69b4bd7..1d41efa6c1f89 100644
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -831,9 +831,5 @@ def test_decompress_cannot_have_flags_compression(self):
         self.assertEqual(out, b'')
 
 
-def test_main(verbose=None):
-    support.run_unittest(TestGzip, TestOpen, TestCommandLine)
-
-
 if __name__ == "__main__":
-    test_main(verbose=True)
+    unittest.main()
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
index 70e562f4052d9..c1494d29ca870 100644
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -1300,21 +1300,9 @@ def test_server_test_ipv4(self, _):
             self.assertEqual(mock_server.address_family, socket.AF_INET)
 
 
-def test_main(verbose=None):
-    cwd = os.getcwd()
-    try:
-        support.run_unittest(
-            RequestHandlerLoggingTestCase,
-            BaseHTTPRequestHandlerTestCase,
-            BaseHTTPServerTestCase,
-            SimpleHTTPServerTestCase,
-            CGIHTTPServerTestCase,
-            SimpleHTTPRequestHandlerTestCase,
-            MiscTestCase,
-            ScriptTestCase
-        )
-    finally:
-        os.chdir(cwd)
+def setUpModule():
+    unittest.addModuleCleanup(os.chdir, os.getcwd())
+
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py
index 21794d911ef69..bb6e083c4aff6 100644
--- a/Lib/test/test_importlib/test_locks.py
+++ b/Lib/test/test_importlib/test_locks.py
@@ -4,6 +4,7 @@
 
 import sys
 import threading
+import unittest
 import weakref
 
 from test import support
@@ -138,15 +139,10 @@ def test_all_locks(self):
  ) = test_util.test_both(LifetimeTests, init=init)
 
 
- at support.reap_threads
-def test_main():
-    support.run_unittest(Frozen_ModuleLockAsRLockTests,
-                         Source_ModuleLockAsRLockTests,
-                         Frozen_DeadlockAvoidanceTests,
-                         Source_DeadlockAvoidanceTests,
-                         Frozen_LifetimeTests,
-                         Source_LifetimeTests)
+def setUpModule():
+    thread_info = support.threading_setup()
+    unittest.addModuleCleanup(support.threading_cleanup, *thread_info)
 
 
 if __name__ == '__main__':
-    test_main()
+    unittets.main()
diff --git a/Lib/test/test_importlib/test_threaded_import.py b/Lib/test/test_importlib/test_threaded_import.py
index d1f8db42fbe37..221d0da20dcc9 100644
--- a/Lib/test/test_importlib/test_threaded_import.py
+++ b/Lib/test/test_importlib/test_threaded_import.py
@@ -14,8 +14,9 @@
 import threading
 import unittest
 from unittest import mock
+from test import support
 from test.support import (
-    verbose, run_unittest, TESTFN, reap_threads,
+    verbose, TESTFN,
     forget, unlink, rmtree, start_threads, script_helper)
 
 def task(N, done, done_tasks, errors):
@@ -257,19 +258,16 @@ def test_multiprocessing_pool_circular_import(self):
         script_helper.assert_python_ok(fn)
 
 
- at reap_threads
-def test_main():
-    old_switchinterval = None
+def setUpModule():
+    thread_info = support.threading_setup()
+    unittest.addModuleCleanup(support.threading_cleanup, *thread_info)
     try:
         old_switchinterval = sys.getswitchinterval()
+        unittest.addModuleCleanup(sys.setswitchinterval, old_switchinterval)
         sys.setswitchinterval(1e-5)
     except AttributeError:
         pass
-    try:
-        run_unittest(ThreadedImportTests)
-    finally:
-        if old_switchinterval is not None:
-            sys.setswitchinterval(old_switchinterval)
+
 
 if __name__ == "__main__":
-    test_main()
+    unittets.main()
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index dc7f5c2427104..17c5d87f8ab45 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -24,7 +24,7 @@
 except ImportError:
     ThreadPoolExecutor = None
 
-from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only
+from test.support import TESTFN, DirsOnSysPath, cpython_only
 from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ
 from test.support.script_helper import assert_python_ok, assert_python_failure
 from test import inspect_fodder as mod
@@ -4081,18 +4081,5 @@ def test_getsource_reload(self):
             self.assertInspectEqual(path, module)
 
 
-def test_main():
-    run_unittest(
-        TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBlockComments,
-        TestBuggyCases, TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
-        TestGetcallargsFunctions, TestGetcallargsMethods,
-        TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
-        TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
-        TestBoundArguments, TestSignaturePrivateHelpers,
-        TestSignatureDefinitions, TestIsDataDescriptor,
-        TestGetClosureVars, TestUnwrap, TestMain, TestReload,
-        TestGetCoroutineState, TestGettingSourceOfToplevelFrames
-    )
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py
index 524346939886d..d238985f11b32 100644
--- a/Lib/test/test_iter.py
+++ b/Lib/test/test_iter.py
@@ -2,7 +2,7 @@
 
 import sys
 import unittest
-from test.support import run_unittest, TESTFN, unlink, cpython_only
+from test.support import TESTFN, unlink, cpython_only
 from test.support import check_free_after_iterating, ALWAYS_EQ, NEVER_EQ
 import pickle
 import collections.abc
@@ -1036,9 +1036,5 @@ def test_error_iter(self):
         self.assertRaises(ZeroDivisionError, iter, BadIterableClass())
 
 
-def test_main():
-    run_unittest(TestCase)
-
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 8a3ffb5584fb8..08fb79506c5ad 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -5365,25 +5365,11 @@ def test__all__(self):
 # Set the locale to the platform-dependent default.  I have no idea
 # why the test does this, but in any case we save the current locale
 # first and restore it at the end.
- at support.run_with_locale('LC_ALL', '')
-def test_main():
-    tests = [
-        BuiltinLevelsTest, BasicFilterTest, CustomLevelsAndFiltersTest,
-        HandlerTest, MemoryHandlerTest, ConfigFileTest, SocketHandlerTest,
-        DatagramHandlerTest, MemoryTest, EncodingTest, WarningsTest,
-        ConfigDictTest, ManagerTest, FormatterTest, BufferingFormatterTest,
-        StreamHandlerTest, LogRecordFactoryTest, ChildLoggerTest,
-        QueueHandlerTest, ShutdownTest, ModuleLevelMiscTest, BasicConfigTest,
-        LoggerAdapterTest, LoggerTest, SMTPHandlerTest, FileHandlerTest,
-        RotatingFileHandlerTest,  LastResortTest, LogRecordTest,
-        ExceptionTest, SysLogHandlerTest, IPv6SysLogHandlerTest, HTTPHandlerTest,
-        NTEventLogHandlerTest, TimedRotatingFileHandlerTest,
-        UnixSocketHandlerTest, UnixDatagramHandlerTest, UnixSysLogHandlerTest,
-        MiscTestCase
-    ]
-    if hasattr(logging.handlers, 'QueueListener'):
-        tests.append(QueueListenerTest)
-    support.run_unittest(*tests)
+def setUpModule():
+    cm = support.run_with_locale('LC_ALL', '')
+    cm.__enter__()
+    unittest.addModuleCleanup(cm.__exit__, None, None, None)
+
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py
index ef7dd6325d49f..ad9484d8ceb36 100644
--- a/Lib/test/test_lzma.py
+++ b/Lib/test/test_lzma.py
@@ -10,7 +10,7 @@
 import unittest
 
 from test.support import (
-    _4G, TESTFN, import_module, bigmemtest, run_unittest, unlink
+    _4G, TESTFN, import_module, bigmemtest, unlink
 )
 
 lzma = import_module("lzma")
@@ -1936,14 +1936,5 @@ def test_filter_properties_roundtrip(self):
 )
 
 
-def test_main():
-    run_unittest(
-        CompressorDecompressorTestCase,
-        CompressDecompressFunctionTestCase,
-        FileTestCase,
-        OpenTestCase,
-        MiscellaneousTestCase,
-    )
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py
index 6f891d413cd8f..37b45005621e7 100644
--- a/Lib/test/test_mailbox.py
+++ b/Lib/test/test_mailbox.py
@@ -2299,15 +2299,9 @@ def test__all__(self):
         support.check__all__(self, mailbox, blacklist=blacklist)
 
 
-def test_main():
-    tests = (TestMailboxSuperclass, TestMaildir, TestMbox, TestMMDF, TestMH,
-             TestBabyl, TestMessage, TestMaildirMessage, TestMboxMessage,
-             TestMHMessage, TestBabylMessage, TestMMDFMessage,
-             TestMessageConversion, TestProxyFile, TestPartialFile,
-             MaildirTestCase, TestFakeMailBox, MiscTestCase)
-    support.run_unittest(*tests)
+def tearDownModule():
     support.reap_children()
 
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py
index 3cf5d7beb144b..96013ed505252 100644
--- a/Lib/test/test_multibytecodec.py
+++ b/Lib/test/test_multibytecodec.py
@@ -380,8 +380,6 @@ class TestHZStateful(TestStateful):
     reset = b'~}'
     expected_reset = expected + reset
 
-def test_main():
-    support.run_unittest(__name__)
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py
index 437fdd2be8d85..b825ca1bdaa29 100644
--- a/Lib/test/test_optparse.py
+++ b/Lib/test/test_optparse.py
@@ -1655,8 +1655,5 @@ def test__all__(self):
         support.check__all__(self, optparse, blacklist=blacklist)
 
 
-def test_main():
-    support.run_unittest(__name__)
-
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_ossaudiodev.py b/Lib/test/test_ossaudiodev.py
index 624fbf21ba7d8..f1b0d642c7eca 100644
--- a/Lib/test/test_ossaudiodev.py
+++ b/Lib/test/test_ossaudiodev.py
@@ -187,7 +187,7 @@ def test_on_closed(self):
         mixer.close()
         self.assertRaises(ValueError, mixer.fileno)
 
-def test_main():
+def setUpModule():
     try:
         dsp = ossaudiodev.open('w')
     except (ossaudiodev.error, OSError) as msg:
@@ -196,7 +196,6 @@ def test_main():
             raise unittest.SkipTest(msg)
         raise
     dsp.close()
-    support.run_unittest(__name__)
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_pipes.py b/Lib/test/test_pipes.py
index 1d538b9898b81..72e1cabab28d7 100644
--- a/Lib/test/test_pipes.py
+++ b/Lib/test/test_pipes.py
@@ -3,7 +3,7 @@
 import string
 import unittest
 import shutil
-from test.support import TESTFN, run_unittest, unlink, reap_children
+from test.support import TESTFN, unlink, reap_children
 
 if os.name != 'posix':
     raise unittest.SkipTest('pipes module only works on posix')
@@ -194,9 +194,10 @@ def testClone(self):
         self.assertNotEqual(id(t.steps), id(u.steps))
         self.assertEqual(t.debugging, u.debugging)
 
-def test_main():
-    run_unittest(SimplePipeTests)
+
+def tearDownModule():
     reap_children()
 
+
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py
index 54725dc641b1d..e48d33dc916d9 100644
--- a/Lib/test/test_pkgutil.py
+++ b/Lib/test/test_pkgutil.py
@@ -1,5 +1,5 @@
 from pathlib import Path
-from test.support import run_unittest, unload, check_warnings, CleanImport
+from test.support import unload, check_warnings, CleanImport
 import unittest
 import sys
 import importlib
@@ -623,9 +623,7 @@ def test_iter_importers_avoids_emulation(self):
             self.assertEqual(len(w.warnings), 0)
 
 
-def test_main():
-    run_unittest(PkgutilTests, PkgutilPEP302Tests, ExtendPathTests,
-                 NestedNamespacePackageTest, ImportlibMigrationTests)
+def tearDownModule():
     # this is necessary if test is run repeated (like when finding leaks)
     import zipimport
     import importlib
@@ -634,4 +632,4 @@ def test_main():
 
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py
index ef966bf0f5608..294131da795a7 100644
--- a/Lib/test/test_poll.py
+++ b/Lib/test/test_poll.py
@@ -7,7 +7,7 @@
 import threading
 import time
 import unittest
-from test.support import TESTFN, run_unittest, reap_threads, cpython_only
+from test.support import TESTFN, reap_threads, cpython_only
 
 try:
     select.poll
@@ -226,8 +226,5 @@ def test_poll_blocks_with_negative_ms(self):
             os.close(w)
 
 
-def test_main():
-    run_unittest(PollTests)
-
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py
index b670afcf4e62e..5228fc46f4b6e 100644
--- a/Lib/test/test_poplib.py
+++ b/Lib/test/test_poplib.py
@@ -11,6 +11,7 @@
 import errno
 import threading
 
+import unittest
 from unittest import TestCase, skipUnless
 from test import support as test_support
 from test.support import hashlib_helper
@@ -533,15 +534,10 @@ def testTimeoutValue(self):
             poplib.POP3(HOST, self.port, timeout=0)
 
 
-def test_main():
-    tests = [TestPOP3Class, TestTimeouts,
-             TestPOP3_SSLClass, TestPOP3_TLSClass]
+def setUpModule():
     thread_info = test_support.threading_setup()
-    try:
-        test_support.run_unittest(*tests)
-    finally:
-        test_support.threading_cleanup(*thread_info)
+    unittest.addModuleCleanup(test_support.threading_cleanup, *thread_info)
 
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index f4edb8bd9575f..890b7e04da364 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -2132,17 +2132,9 @@ def test_utime(self):
                 os.utime("path", dir_fd=0)
 
 
-def test_main():
-    try:
-        support.run_unittest(
-            PosixTester,
-            PosixGroupsTester,
-            TestPosixSpawn,
-            TestPosixSpawnP,
-            TestPosixWeaklinking
-        )
-    finally:
-        support.reap_children()
+def tearDownModule():
+    support.reap_children()
+
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py
index 233649899ec20..3bb367b057873 100644
--- a/Lib/test/test_profile.py
+++ b/Lib/test/test_profile.py
@@ -6,7 +6,7 @@
 import os
 from difflib import unified_diff
 from io import StringIO
-from test.support import TESTFN, run_unittest, unlink, temp_dir, change_cwd
+from test.support import TESTFN, unlink, temp_dir, change_cwd
 from contextlib import contextmanager
 
 import profile
@@ -155,12 +155,10 @@ def silent():
     finally:
         sys.stdout = stdout
 
-def test_main():
-    run_unittest(ProfileTest)
 
 def main():
     if '-r' not in sys.argv:
-        test_main()
+        unittest.main()
     else:
         regenerate_expected_output(__file__, ProfileTest)
 
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 0bbdc42c635be..9b0e94de49d60 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -1569,20 +1569,11 @@ def test_sys_path_adjustment_when_curdir_already_included(self):
                 self.assertIsNone(self._get_revised_path(trailing_argv0dir))
 
 
- at reap_threads
-def test_main():
-    try:
-        test.support.run_unittest(PydocDocTest,
-                                  PydocImportTest,
-                                  TestDescriptions,
-                                  PydocServerTest,
-                                  PydocUrlHandlerTest,
-                                  TestHelper,
-                                  PydocWithMetaClasses,
-                                  TestInternalUtilities,
-                                  )
-    finally:
-        reap_children()
+def setUpModule():
+    thread_info = test.support.threading_setup()
+    unittest.addModuleCleanup(test.support.threading_cleanup, *thread_info)
+    unittest.addModuleCleanup(reap_children)
+
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py
index e5ece5284cf15..089dbf9b4015e 100644
--- a/Lib/test/test_resource.py
+++ b/Lib/test/test_resource.py
@@ -172,8 +172,5 @@ def __getitem__(self, key):
                          limits)
 
 
-def test_main(verbose=None):
-    support.run_unittest(ResourceTest)
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py
index ce3a422b502a0..3e7fedaa6da70 100644
--- a/Lib/test/test_sax.py
+++ b/Lib/test/test_sax.py
@@ -22,7 +22,7 @@
 from urllib.error import URLError
 import urllib.request
 from test import support
-from test.support import findfile, run_unittest, FakePath, TESTFN
+from test.support import findfile, FakePath, TESTFN
 
 TEST_XMLFILE = findfile("test.xml", subdir="xmltestdata")
 TEST_XMLFILE_OUT = findfile("test.xml.out", subdir="xmltestdata")
@@ -1353,19 +1353,5 @@ def test_nsattrs_wattr(self):
         self.assertEqual(attrs.getQNameByName((ns_uri, "attr")), "ns:attr")
 
 
-def test_main():
-    run_unittest(MakeParserTest,
-                 ParseTest,
-                 SaxutilsTest,
-                 PrepareInputSourceTest,
-                 StringXmlgenTest,
-                 BytesXmlgenTest,
-                 WriterXmlgenTest,
-                 StreamWriterXmlgenTest,
-                 StreamReaderWriterXmlgenTest,
-                 ExpatReaderTest,
-                 ErrorReportingTest,
-                 XmlReaderTest)
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py
index 2274c39a79a53..3a3f87760a975 100644
--- a/Lib/test/test_selectors.py
+++ b/Lib/test/test_selectors.py
@@ -48,7 +48,7 @@ def find_ready_matching(ready, flag):
     return match
 
 
-class BaseSelectorTestCase(unittest.TestCase):
+class BaseSelectorTestCase:
 
     def make_socketpair(self):
         rd, wr = socketpair()
@@ -492,26 +492,28 @@ def test_above_fd_setsize(self):
         self.assertEqual(NUM_FDS // 2, len(fds))
 
 
-class DefaultSelectorTestCase(BaseSelectorTestCase):
+class DefaultSelectorTestCase(BaseSelectorTestCase, unittest.TestCase):
 
     SELECTOR = selectors.DefaultSelector
 
 
-class SelectSelectorTestCase(BaseSelectorTestCase):
+class SelectSelectorTestCase(BaseSelectorTestCase, unittest.TestCase):
 
     SELECTOR = selectors.SelectSelector
 
 
 @unittest.skipUnless(hasattr(selectors, 'PollSelector'),
                      "Test needs selectors.PollSelector")
-class PollSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn):
+class PollSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn,
+                           unittest.TestCase):
 
     SELECTOR = getattr(selectors, 'PollSelector', None)
 
 
 @unittest.skipUnless(hasattr(selectors, 'EpollSelector'),
                      "Test needs selectors.EpollSelector")
-class EpollSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn):
+class EpollSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn,
+                            unittest.TestCase):
 
     SELECTOR = getattr(selectors, 'EpollSelector', None)
 
@@ -528,7 +530,8 @@ def test_register_file(self):
 
 @unittest.skipUnless(hasattr(selectors, 'KqueueSelector'),
                      "Test needs selectors.KqueueSelector)")
-class KqueueSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn):
+class KqueueSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn,
+                             unittest.TestCase):
 
     SELECTOR = getattr(selectors, 'KqueueSelector', None)
 
@@ -560,19 +563,15 @@ def test_empty_select_timeout(self):
 
 @unittest.skipUnless(hasattr(selectors, 'DevpollSelector'),
                      "Test needs selectors.DevpollSelector")
-class DevpollSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn):
+class DevpollSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn,
+                              unittest.TestCase):
 
     SELECTOR = getattr(selectors, 'DevpollSelector', None)
 
 
-
-def test_main():
-    tests = [DefaultSelectorTestCase, SelectSelectorTestCase,
-             PollSelectorTestCase, EpollSelectorTestCase,
-             KqueueSelectorTestCase, DevpollSelectorTestCase]
-    support.run_unittest(*tests)
+def tearDownModule():
     support.reap_children()
 
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index f928bcea2d1a5..42ebcc04dc2b8 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -2281,6 +2281,7 @@ def test_bio_read_write_data(self):
         self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
 
 
+ at support.requires_resource('network')
 class NetworkedTests(unittest.TestCase):
 
     def test_timeout_connect_ex(self):
@@ -4812,7 +4813,7 @@ def sni_cb(sock, servername, ctx):
                 s.connect((HOST, server.port))
 
 
-def test_main(verbose=False):
+def setUpModule():
     if support.verbose:
         plats = {
             'Mac': platform.mac_ver,
@@ -4843,20 +4844,9 @@ def test_main(verbose=False):
         if not os.path.exists(filename):
             raise support.TestFailed("Can't read certificate file %r" % filename)
 
-    tests = [
-        ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests,
-        SSLObjectTests, SimpleBackgroundTests, ThreadedTests,
-        TestPostHandshakeAuth, TestSSLDebug
-    ]
-
-    if support.is_resource_enabled('network'):
-        tests.append(NetworkedTests)
-
     thread_info = support.threading_setup()
-    try:
-        support.run_unittest(*tests)
-    finally:
-        support.threading_cleanup(*thread_info)
+    unittest.addModuleCleanup(support.threading_cleanup, *thread_info)
+
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index 60a7741194f2f..159346dca6194 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -716,9 +716,5 @@ def _warn_about_deprecation():
     )
 
 
-def test_main():
-    tests = [TestSupport]
-    support.run_unittest(*tests)
-
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py
index fa974d181136e..cd142ab6b0335 100644
--- a/Lib/test/test_tcl.py
+++ b/Lib/test/test_tcl.py
@@ -799,8 +799,5 @@ def setUpModule():
         print('patchlevel =', tcl.call('info', 'patchlevel'))
 
 
-def test_main():
-    support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_threadsignals.py b/Lib/test/test_threadsignals.py
index eeacd3698cb13..b000adc32232a 100644
--- a/Lib/test/test_threadsignals.py
+++ b/Lib/test/test_threadsignals.py
@@ -230,7 +230,7 @@ def send_signals():
             signal.signal(signal.SIGUSR1, old_handler)
 
 
-def test_main():
+def setUpModule():
     global signal_blackboard
 
     signal_blackboard = { signal.SIGUSR1 : {'tripped': 0, 'tripped_by': 0 },
@@ -238,10 +238,8 @@ def test_main():
                           signal.SIGALRM : {'tripped': 0, 'tripped_by': 0 } }
 
     oldsigs = registerSignals(handle_signals, handle_signals, handle_signals)
-    try:
-        support.run_unittest(ThreadSignals)
-    finally:
-        registerSignals(*oldsigs)
+    unittest.addModuleCleanup(registerSignals, *oldsigs)
+
 
 if __name__ == '__main__':
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_timeout.py b/Lib/test/test_timeout.py
index ac803f5d63823..fb73b5a45208f 100644
--- a/Lib/test/test_timeout.py
+++ b/Lib/test/test_timeout.py
@@ -290,13 +290,9 @@ def testRecvfromTimeout(self):
         self._sock_operation(1, 1.5, 'recvfrom', 1024)
 
 
-def test_main():
+def setUpModule():
     support.requires('network')
-    support.run_unittest(
-        CreationTestCase,
-        TCPTimeoutTestCase,
-        UDPTimeoutTestCase,
-    )
+
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py
index b10d1798c2977..687e2b65733da 100644
--- a/Lib/test/test_tracemalloc.py
+++ b/Lib/test/test_tracemalloc.py
@@ -1081,15 +1081,5 @@ def test_stop_untrack(self):
             self.untrack()
 
 
-def test_main():
-    support.run_unittest(
-        TestTraceback,
-        TestTracemallocEnabled,
-        TestSnapshot,
-        TestFilters,
-        TestCommandLine,
-        TestCAPI,
-    )
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_unicode_file.py b/Lib/test/test_unicode_file.py
index e8feb42c6b0c2..a9412e40e761a 100644
--- a/Lib/test/test_unicode_file.py
+++ b/Lib/test/test_unicode_file.py
@@ -5,7 +5,7 @@
 import unicodedata
 
 import unittest
-from test.support import (run_unittest, rmtree, change_cwd,
+from test.support import (rmtree, change_cwd,
     TESTFN_ENCODING, TESTFN_UNICODE, TESTFN_UNENCODABLE, create_empty_file)
 
 if not os.path.supports_unicode_filenames:
@@ -133,8 +133,6 @@ def test_directories(self):
             self._do_directory(TESTFN_UNENCODABLE+ext,
                                TESTFN_UNENCODABLE+ext)
 
-def test_main():
-    run_unittest(__name__)
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_unicode_file_functions.py b/Lib/test/test_unicode_file_functions.py
index 1cd0d621cd4b3..e36c7cddf3e9a 100644
--- a/Lib/test/test_unicode_file_functions.py
+++ b/Lib/test/test_unicode_file_functions.py
@@ -181,15 +181,5 @@ class UnicodeNFKDFileTests(UnicodeFileTests):
     normal_form = 'NFKD'
 
 
-def test_main():
-    support.run_unittest(
-        UnicodeFileTests,
-        UnicodeNFCFileTests,
-        UnicodeNFDFileTests,
-        UnicodeNFKCFileTests,
-        UnicodeNFKDFileTests,
-    )
-
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_unittest.py b/Lib/test/test_unittest.py
index bfc3ded6f128d..1079c7df2e51c 100644
--- a/Lib/test/test_unittest.py
+++ b/Lib/test/test_unittest.py
@@ -3,14 +3,14 @@
 from test import support
 
 
-def test_main():
-    # used by regrtest
-    support.run_unittest(unittest.test.suite())
-    support.reap_children()
-
 def load_tests(*_):
     # used by unittest
     return unittest.test.suite()
 
+
+def tearDownModule():
+    support.reap_children()
+
+
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py
index ed426b05a7198..e73132ab69974 100644
--- a/Lib/test/test_urllib2_localnet.py
+++ b/Lib/test/test_urllib2_localnet.py
@@ -660,17 +660,10 @@ def test_line_iteration(self):
         self.assertEqual(index + 1, len(lines))
 
 
-threads_key = None
-
 def setUpModule():
-    # Store the threading_setup in a key and ensure that it is cleaned up
-    # in the tearDown
-    global threads_key
-    threads_key = support.threading_setup()
-
-def tearDownModule():
-    if threads_key:
-        support.threading_cleanup(*threads_key)
+    thread_info = support.threading_setup()
+    unittest.addModuleCleanup(support.threading_cleanup, *thread_info)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py
index 5c25ec8f7ec67..1e689f74851b9 100644
--- a/Lib/test/test_winreg.py
+++ b/Lib/test/test_winreg.py
@@ -489,12 +489,9 @@ def test_exception_numbers(self):
         with self.assertRaises(FileNotFoundError) as ctx:
             QueryValue(HKEY_CLASSES_ROOT, 'some_value_that_does_not_exist')
 
-def test_main():
-    support.run_unittest(LocalWinregTests, RemoteWinregTests,
-                         Win64WinregTests)
 
 if __name__ == "__main__":
     if not REMOTE_NAME:
         print("Remote registry calls can be tested using",
               "'test_winreg.py --remote \\\\machine_name'")
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py
index 75544035381a9..83b618b749162 100644
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -1502,16 +1502,10 @@ def test_xmlrpcserver_has_use_builtin_types_flag(self):
         self.assertTrue(server.use_builtin_types)
 
 
- at support.reap_threads
-def test_main():
-    support.run_unittest(XMLRPCTestCase, HelperTestCase, DateTimeTestCase,
-            BinaryTestCase, FaultTestCase, UseBuiltinTypesTestCase,
-            SimpleServerTestCase, SimpleServerEncodingTestCase,
-            KeepaliveServerTestCase1, KeepaliveServerTestCase2,
-            GzipServerTestCase, GzipUtilTestCase, HeadersServerTestCase,
-            MultiPathServerTestCase, ServerProxyTestCase, FailingServerTestCase,
-            CGIHandlerTestCase, SimpleXMLRPCDispatcherTestCase)
+def setUpModule():
+    thread_info = support.threading_setup()
+    unittest.addModuleCleanup(support.threading_cleanup, *thread_info)
 
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_xmlrpc_net.py b/Lib/test/test_xmlrpc_net.py
index f3652b86f7510..51167b28bc5a1 100644
--- a/Lib/test/test_xmlrpc_net.py
+++ b/Lib/test/test_xmlrpc_net.py
@@ -5,6 +5,9 @@
 import xmlrpc.client as xmlrpclib
 
 
+support.requires("network")
+
+
 @unittest.skip('XXX: buildbot.python.org/all/xmlrpc/ is gone')
 class PythonBuildersTest(unittest.TestCase):
 
@@ -24,9 +27,5 @@ def test_python_builders(self):
         self.assertTrue([x for x in builders if "3.x" in x], builders)
 
 
-def test_main():
-    support.requires("network")
-    support.run_unittest(PythonBuildersTest)
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py
index 80c98b4b4661d..2e2438863da28 100644
--- a/Lib/test/test_zipimport.py
+++ b/Lib/test/test_zipimport.py
@@ -766,15 +766,9 @@ def _testBogusZipFile(self):
             zipimport._zip_directory_cache.clear()
 
 
-def test_main():
-    try:
-        support.run_unittest(
-              UncompressedZipImportTestCase,
-              CompressedZipImportTestCase,
-              BadFileZipImportTestCase,
-            )
-    finally:
-        support.unlink(TESTMOD)
+def tearDownModule():
+    support.unlink(TESTMOD)
+
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()



More information about the Python-checkins mailing list