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

serhiy-storchaka webhook-mailer at python.org
Sun Sep 19 15:36:12 EDT 2021


https://github.com/python/cpython/commit/bedce3538cca3469ac3efc614ef062367cbb2ff1
commit: bedce3538cca3469ac3efc614ef062367cbb2ff1
branch: 3.10
author: Serhiy Storchaka <storchaka at gmail.com>
committer: serhiy-storchaka <storchaka at gmail.com>
date: 2021-09-19T22:36:03+03:00
summary:

[3.10] bpo-45229: Remove test_main in many tests (GH-28405) (GH-28455)

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 abc2a189ffc5f..ca61bd62e7529 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -687,9 +687,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)
@@ -708,16 +707,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 376aa6151701a..0927281f69c92 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):
@@ -5397,13 +5396,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 6ffec918ebbd5..c93ed5be7fbde 100644
--- a/Lib/test/test_cmd_line_script.py
+++ b/Lib/test/test_cmd_line_script.py
@@ -739,9 +739,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 abd7e39cc5ae7..c6a261b418b54 100644
--- a/Lib/test/test_complex.py
+++ b/Lib/test/test_complex.py
@@ -777,8 +777,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 c67911b8cdf71..b8862fd6fcace 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 a9778282d90a4..f0dc6bb45c5a5 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
@@ -4350,19 +4350,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 5794b75ba3f6f..c969a3f7665d3 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -5488,25 +5488,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 6e3618f6b0f98..800fe38fb486a 100644
--- a/Lib/test/test_pkgutil.py
+++ b/Lib/test/test_pkgutil.py
@@ -1,4 +1,3 @@
-from test.support import run_unittest
 from test.support.import_helper import unload, CleanImport
 from test.support.warnings_helper import check_warnings
 import unittest
@@ -580,9 +579,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
@@ -591,4 +588,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 0afa3e6fce181..44c16989716a0 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -1571,20 +1571,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 f4a84701c5d8b..a485f7d4c3c0c 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -2343,6 +2343,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):
@@ -4869,7 +4870,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,
@@ -4900,20 +4901,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 = 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 11ca0c2fb2d2f..79290986c494d 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -709,9 +709,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 6e5ef097c888f..30f043172478f 100644
--- a/Lib/test/test_tcl.py
+++ b/Lib/test/test_tcl.py
@@ -804,8 +804,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 8acfeef2745fc..19d3a880f4cd7 100644
--- a/Lib/test/test_zipimport.py
+++ b/Lib/test/test_zipimport.py
@@ -856,15 +856,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