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

serhiy-storchaka webhook-mailer at python.org
Sun Sep 19 08:27:38 EDT 2021


https://github.com/python/cpython/commit/40348acc180580371d25f75f46b27048e35f2435
commit: 40348acc180580371d25f75f46b27048e35f2435
branch: main
author: Serhiy Storchaka <storchaka at gmail.com>
committer: serhiy-storchaka <storchaka at gmail.com>
date: 2021-09-19T15:27:33+03:00
summary:

bpo-45229: Remove test_main in many tests (GH-28405)

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.

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 04516a5f9d719..bc40bba909496 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -695,9 +695,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)
@@ -716,16 +715,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 99269103c5b57..8babab399543b 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -12,7 +12,6 @@
 
 from io import StringIO
 
-from test import support
 from test.support import os_helper
 from unittest import mock
 class StdIOBuffer(StringIO):
@@ -5416,13 +5415,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 398698c79c16d..6ec59531fa88f 100644
--- a/Lib/test/test_bdb.py
+++ b/Lib/test/test_bdb.py
@@ -57,7 +57,6 @@
 import linecache
 from contextlib import contextmanager
 from itertools import islice, repeat
-import test.support
 from test.support import import_helper
 from test.support import os_helper
 
@@ -1193,13 +1192,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 a3214c90ed61e..4b32aad2419f4 100644
--- a/Lib/test/test_bool.py
+++ b/Lib/test/test_bool.py
@@ -1,7 +1,6 @@
 # Test properties of bool promised by PEP 285
 
 import unittest
-from test import support
 from test.support import os_helper
 
 import os
@@ -370,8 +369,6 @@ def f(x):
         f(x)
         self.assertGreaterEqual(x.count, 1)
 
-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 7913beb87a352..9965c1fe2e5f1 100644
--- a/Lib/test/test_bz2.py
+++ b/Lib/test/test_bz2.py
@@ -1005,15 +1005,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 cbf9ff2a863c3..d93e98f372532 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -864,9 +864,10 @@ def test_tokenizer_error_with_stdin(self):
     def test_decoding_error_at_the_end_of_the_line(self):
         self.check_string(br"'\u1f'")
 
-def test_main():
-    support.run_unittest(CmdLineTest, IgnoreEnvironmentTest, SyntaxErrorTests)
+
+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 874f4db478a39..9fe748c187060 100644
--- a/Lib/test/test_cmd_line_script.py
+++ b/Lib/test/test_cmd_line_script.py
@@ -738,9 +738,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 1cd025ed53a5d..e046577b935e9 100644
--- a/Lib/test/test_complex.py
+++ b/Lib/test/test_complex.py
@@ -789,8 +789,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 eae98d690bd97..b0df12c66c901 100644
--- a/Lib/test/test_concurrent_futures.py
+++ b/Lib/test/test_concurrent_futures.py
@@ -1515,16 +1515,10 @@ def test_multiple_set_exception(self):
         self.assertEqual(f.exception(), e)
 
 
-_threads_key = None
-
 def setUpModule():
-    global _threads_key
-    _threads_key = threading_helper.threading_setup()
-
-
-def tearDownModule():
-    threading_helper.threading_cleanup(*_threads_key)
-    multiprocessing.util._cleanup_tests()
+    unittest.addModuleCleanup(multiprocessing.util._cleanup_tests)
+    thread_info = threading_helper.threading_setup()
+    unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info)
 
 
 if __name__ == "__main__":
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 71b6954b6fca3..9b919e7824445 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -4996,8 +4996,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 ...
 
@@ -5735,12 +5738,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 9a24e00f64b4a..6afd90af8442a 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 90bfc70a133ae..4b40af0213234 100644
--- a/Lib/test/test_distutils.py
+++ b/Lib/test/test_distutils.py
@@ -15,16 +15,14 @@
     import distutils.tests
 
 
-def test_main():
-    # used by regrtest
-    support.run_unittest(distutils.tests.test_suite())
-    support.reap_children()
-
-
 def load_tests(*_):
     # used by unittest
     return distutils.tests.test_suite()
 
 
+def tearDownModule():
+    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 83ee7a5b0d012..fc8c39365f12b 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, run_unittest, cpython_only)
+from test.support import verbose, cpython_only
 from test.support.import_helper import import_module
 from test.support.os_helper import TESTFN, unlink
 
@@ -210,8 +210,5 @@ def test_fcntl_f_pipesize(self):
             os.close(test_pipe_w)
 
 
-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 64ba5a0e18169..9b5ac12bccc58 100644
--- a/Lib/test/test_filecmp.py
+++ b/Lib/test/test_filecmp.py
@@ -246,8 +246,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 cdca5a8599655..4269b0e53f56d 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 run_unittest, cpython_only, swap_attr, gc_collect
+from test.support import cpython_only, swap_attr, gc_collect
 from test.support.os_helper import (TESTFN, TESTFN_UNICODE, make_bad_fd)
 from test.support.warnings_helper import check_warnings
 from collections import UserList
@@ -606,15 +606,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 3492ba44f2103..56e3d8ab8528a 100644
--- a/Lib/test/test_ftplib.py
+++ b/Lib/test/test_ftplib.py
@@ -10,6 +10,7 @@
 import os
 import threading
 import time
+import unittest
 try:
     import ssl
 except ImportError:
@@ -1144,18 +1145,10 @@ def test__all__(self):
         support.check__all__(self, ftplib, not_exported=not_exported)
 
 
-def test_main():
-    tests = [TestFTPClass, TestTimeouts,
-             TestIPv6Environment,
-             TestTLS_FTPClassMixin, TestTLS_FTPClass,
-             MiscTestCase]
-
+def setUpModule():
     thread_info = threading_helper.threading_setup()
-    try:
-        support.run_unittest(*tests)
-    finally:
-        threading_helper.threading_cleanup(*thread_info)
+    unittest.addModuleCleanup(threading_helper.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 1528cf6e20ee6..6c28b2b677cee 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)
 from test.support.import_helper import import_module
 from test.support.os_helper import temp_dir, TESTFN, unlink
@@ -1389,30 +1389,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 c71d055297e0c..d0bde3fd040e6 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
+from test.support import check_syntax_error
 from test.support.warnings_helper import check_warnings
 import unittest
 import warnings
@@ -53,10 +53,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 7b51e45aad92b..f86e767ac0e59 100644
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -10,7 +10,6 @@
 import sys
 import unittest
 from subprocess import PIPE, Popen
-from test import support
 from test.support import import_helper
 from test.support import os_helper
 from test.support import _4G, bigmemtest
@@ -842,9 +841,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 69790ec746314..1cc020f63539d 100644
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -1302,21 +1302,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 0e94ce91801d6..9290bac80a78a 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
@@ -139,15 +140,10 @@ def test_all_locks(self):
  ) = test_util.test_both(LifetimeTests, init=init)
 
 
- at threading_helper.reap_threads
-def test_main():
-    support.run_unittest(Frozen_ModuleLockAsRLockTests,
-                         Source_ModuleLockAsRLockTests,
-                         Frozen_DeadlockAvoidanceTests,
-                         Source_DeadlockAvoidanceTests,
-                         Frozen_LifetimeTests,
-                         Source_LifetimeTests)
+def setUpModule():
+    thread_info = threading_helper.threading_setup()
+    unittest.addModuleCleanup(threading_helper.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 03bde96de6c29..76b028eac97bf 100644
--- a/Lib/test/test_importlib/test_threaded_import.py
+++ b/Lib/test/test_importlib/test_threaded_import.py
@@ -14,7 +14,7 @@
 import threading
 import unittest
 from unittest import mock
-from test.support import (verbose, run_unittest)
+from test.support import verbose
 from test.support.import_helper import forget
 from test.support.os_helper import (TESTFN, unlink, rmtree)
 from test.support import script_helper, threading_helper
@@ -258,19 +258,16 @@ def test_multiprocessing_pool_circular_import(self):
         script_helper.assert_python_ok(fn)
 
 
- at threading_helper.reap_threads
-def test_main():
-    old_switchinterval = None
+def setUpModule():
+    thread_info = threading_helper.threading_setup()
+    unittest.addModuleCleanup(threading_helper.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 e87311ac0230f..0e9191e5073cc 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, cpython_only
+from test.support import cpython_only
 from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ
 from test.support.import_helper import DirsOnSysPath
 from test.support.os_helper import TESTFN
@@ -4343,19 +4343,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,
-        TestGetsourceInteractive,
-    )
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py
index 20cb9c0680914..554f602f6252c 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, cpython_only
+from test.support import cpython_only
 from test.support.os_helper import TESTFN, unlink
 from test.support import check_free_after_iterating, ALWAYS_EQ, NEVER_EQ
 import pickle
@@ -1037,9 +1037,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 9998f1a02e4c9..211fe4bbd7bac 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -5514,25 +5514,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 1e2066b89168f..145c8cfced408 100644
--- a/Lib/test/test_lzma.py
+++ b/Lib/test/test_lzma.py
@@ -9,9 +9,7 @@
 from test import support
 import unittest
 
-from test.support import (
-    _4G, bigmemtest, run_unittest
-)
+from test.support import _4G, bigmemtest
 from test.support.import_helper import import_module
 from test.support.os_helper import (
     TESTFN, unlink
@@ -1941,14 +1939,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 8a5d69246228e..604fc4525f53e 100644
--- a/Lib/test/test_mailbox.py
+++ b/Lib/test/test_mailbox.py
@@ -2300,15 +2300,9 @@ def test__all__(self):
                              not_exported={"linesep", "fcntl"})
 
 
-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 3efa1505e5c92..cf8bb5e3a0520 100644
--- a/Lib/test/test_multibytecodec.py
+++ b/Lib/test/test_multibytecodec.py
@@ -403,8 +403,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 1ed6bf9f919a2..28b274462388e 100644
--- a/Lib/test/test_optparse.py
+++ b/Lib/test/test_optparse.py
@@ -1656,8 +1656,5 @@ def test__all__(self):
         support.check__all__(self, optparse, not_exported=not_exported)
 
 
-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 d3766e580b984..ebce3e9c272f9 100644
--- a/Lib/test/test_ossaudiodev.py
+++ b/Lib/test/test_ossaudiodev.py
@@ -188,7 +188,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:
@@ -197,7 +197,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 6a13b36d1cb70..6335e7cbe09c4 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 run_unittest, reap_children, unix_shell
+from test.support import reap_children, unix_shell
 from test.support.os_helper import TESTFN, unlink
 
 
@@ -199,9 +199,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 3c29080f2054f..0cc99e0cc2276 100644
--- a/Lib/test/test_pkgutil.py
+++ b/Lib/test/test_pkgutil.py
@@ -1,5 +1,4 @@
 from pathlib import Path
-from test.support import run_unittest
 from test.support.import_helper import unload, CleanImport
 from test.support.warnings_helper import check_warnings
 import unittest
@@ -626,9 +625,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
@@ -637,4 +634,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 de62350696a92..82bbb3af9f1b3 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 run_unittest, cpython_only
+from test.support import cpython_only
 from test.support import threading_helper
 from test.support.os_helper import TESTFN
 
@@ -229,8 +229,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 8dd6ea69c0d1a..44cf5231f9d23 100644
--- a/Lib/test/test_poplib.py
+++ b/Lib/test/test_poplib.py
@@ -9,6 +9,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
@@ -538,15 +539,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 = threading_helper.threading_setup()
-    try:
-        test_support.run_unittest(*tests)
-    finally:
-        threading_helper.threading_cleanup(*thread_info)
+    unittest.addModuleCleanup(threading_helper.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 e4666884ce06a..56b72f465c1c0 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -2171,17 +2171,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 7de7d52ff8365..d97fe447c38b0 100644
--- a/Lib/test/test_profile.py
+++ b/Lib/test/test_profile.py
@@ -6,7 +6,6 @@
 import os
 from difflib import unified_diff
 from io import StringIO
-from test.support import run_unittest
 from test.support.os_helper import TESTFN, unlink, temp_dir, change_cwd
 from contextlib import contextmanager
 
@@ -156,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 a952ab93a6f1d..25ac1fb59d4c4 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -1581,20 +1581,11 @@ def test_sys_path_adjustment_when_curdir_already_included(self):
                 self.assertIsNone(self._get_revised_path(trailing_argv0dir))
 
 
- at threading_helper.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 = threading_helper.threading_setup()
+    unittest.addModuleCleanup(threading_helper.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 d909e316b7fd6..f2642c6ba181d 100644
--- a/Lib/test/test_resource.py
+++ b/Lib/test/test_resource.py
@@ -174,8 +174,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 801143f9b5f81..eda4e6a46df43 100644
--- a/Lib/test/test_sax.py
+++ b/Lib/test/test_sax.py
@@ -24,7 +24,7 @@
 from urllib.error import URLError
 import urllib.request
 from test.support import os_helper
-from test.support import findfile, run_unittest
+from test.support import findfile
 from test.support.os_helper import FakePath, TESTFN
 
 
@@ -1506,22 +1506,5 @@ def characters(self, content):
         self.assertEqual(self.char_index, 2)
 
 
-def test_main():
-    run_unittest(MakeParserTest,
-                 ParseTest,
-                 SaxutilsTest,
-                 PrepareInputSourceTest,
-                 StringXmlgenTest,
-                 BytesXmlgenTest,
-                 WriterXmlgenTest,
-                 StreamWriterXmlgenTest,
-                 StreamReaderWriterXmlgenTest,
-                 ExpatReaderTest,
-                 ErrorReportingTest,
-                 XmlReaderTest,
-                 LexicalHandlerTest,
-                 CDATAHandlerTest)
-
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py
index 851b1fc1b9e0c..fe6b725a4bd05 100644
--- a/Lib/test/test_selectors.py
+++ b/Lib/test/test_selectors.py
@@ -49,7 +49,7 @@ def find_ready_matching(ready, flag):
     return match
 
 
-class BaseSelectorTestCase(unittest.TestCase):
+class BaseSelectorTestCase:
 
     def make_socketpair(self):
         rd, wr = socketpair()
@@ -493,26 +493,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)
 
@@ -529,7 +531,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)
 
@@ -561,19 +564,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 556c1cf2792ad..db0539bd5fb3c 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -2344,6 +2344,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):
@@ -5014,7 +5015,7 @@ def test_verifymode(self):
         enum._test_simple_enum(CheckedVerifyMode, ssl.VerifyMode)
 
 
-def test_main(verbose=False):
+def setUpModule():
     if support.verbose:
         plats = {
             'Mac': platform.mac_ver,
@@ -5045,20 +5046,11 @@ 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, TestEnumerations,
-    ]
-
-    if support.is_resource_enabled('network'):
-        tests.append(NetworkedTests)
 
+def setUpModule():
     thread_info = threading_helper.threading_setup()
-    try:
-        support.run_unittest(*tests)
-    finally:
-        threading_helper.threading_cleanup(*thread_info)
+    unittest.addModuleCleanup(threading_helper.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 44fe3348749e8..8b55352b6eecc 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -714,9 +714,5 @@ def test_print_warning(self):
     # SuppressCrashReport
 
 
-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 6970ede6d5232..f18baa54e4a01 100644
--- a/Lib/test/test_tcl.py
+++ b/Lib/test/test_tcl.py
@@ -751,8 +751,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 15e8078e93662..bac82b8a44511 100644
--- a/Lib/test/test_threadsignals.py
+++ b/Lib/test/test_threadsignals.py
@@ -4,7 +4,6 @@
 import signal
 import os
 import sys
-from test import support
 from test.support import threading_helper
 import _thread as thread
 import time
@@ -231,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 },
@@ -239,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 823d5c3e1767e..70a0175d77104 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 556656747bbcb..82be98dfd8f5a 100644
--- a/Lib/test/test_tracemalloc.py
+++ b/Lib/test/test_tracemalloc.py
@@ -1082,15 +1082,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 e397949187983..80c22c6cdd1da 100644
--- a/Lib/test/test_unicode_file.py
+++ b/Lib/test/test_unicode_file.py
@@ -6,7 +6,6 @@
 import unicodedata
 
 import unittest
-from test.support import run_unittest
 from test.support.os_helper import (rmtree, change_cwd, TESTFN_UNICODE,
     TESTFN_UNENCODABLE, create_empty_file)
 
@@ -136,8 +135,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 7ef11aac9f8ef..54916dec4eafa 100644
--- a/Lib/test/test_unicode_file_functions.py
+++ b/Lib/test/test_unicode_file_functions.py
@@ -5,7 +5,6 @@
 import unittest
 import warnings
 from unicodedata import normalize
-from test import support
 from test.support import os_helper
 
 
@@ -185,15 +184,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 ebb43c30b4d50..36fb05d3db0e2 100644
--- a/Lib/test/test_urllib2_localnet.py
+++ b/Lib/test/test_urllib2_localnet.py
@@ -661,17 +661,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 = threading_helper.threading_setup()
-
-def tearDownModule():
-    if threads_key:
-        threading_helper.threading_cleanup(*threads_key)
+    thread_info = threading_helper.threading_setup()
+    unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py
index 487abcd8d9531..fedfbe9b44765 100644
--- a/Lib/test/test_winreg.py
+++ b/Lib/test/test_winreg.py
@@ -3,7 +3,6 @@
 
 import os, sys, errno
 import unittest
-from test import support
 from test.support import import_helper
 import threading
 from platform import machine, win32_edition
@@ -490,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 a9f67466071bc..85e27ad4631d2 100644
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -1504,16 +1504,10 @@ def test_xmlrpcserver_has_use_builtin_types_flag(self):
         self.assertTrue(server.use_builtin_types)
 
 
- at threading_helper.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 = threading_helper.threading_setup()
+    unittest.addModuleCleanup(threading_helper.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 486200af70391..392dcfa87a19b 100644
--- a/Lib/test/test_zipimport.py
+++ b/Lib/test/test_zipimport.py
@@ -861,15 +861,9 @@ def _testBogusZipFile(self):
             zipimport._zip_directory_cache.clear()
 
 
-def test_main():
-    try:
-        support.run_unittest(
-              UncompressedZipImportTestCase,
-              CompressedZipImportTestCase,
-              BadFileZipImportTestCase,
-            )
-    finally:
-        os_helper.unlink(TESTMOD)
+def tearDownModule():
+    os_helper.unlink(TESTMOD)
+
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()



More information about the Python-checkins mailing list