99import unittest
1010
1111from test import support
12- from test .support import TestStats
1312from test .support import threading_helper
1413
15- from .result import State , TestResult
14+ from .filter import match_test
15+ from .result import State , TestResult , TestStats
1616from .runtests import RunTests
1717from .save_env import saved_test_environment
1818from .setup import setup_tests
19+ from .testresult import get_test_runner
1920from .utils import (
2021 TestName ,
2122 clear_caches , remove_testfn , abs_module_name , print_warning )
@@ -33,7 +34,47 @@ def run_unittest(test_mod):
3334 print (error , file = sys .stderr )
3435 if loader .errors :
3536 raise Exception ("errors while loading tests" )
36- return support .run_unittest (tests )
37+ _filter_suite (tests , match_test )
38+ return _run_suite (tests )
39+
40+ def _filter_suite (suite , pred ):
41+ """Recursively filter test cases in a suite based on a predicate."""
42+ newtests = []
43+ for test in suite ._tests :
44+ if isinstance (test , unittest .TestSuite ):
45+ _filter_suite (test , pred )
46+ newtests .append (test )
47+ else :
48+ if pred (test ):
49+ newtests .append (test )
50+ suite ._tests = newtests
51+
52+ def _run_suite (suite ):
53+ """Run tests from a unittest.TestSuite-derived class."""
54+ runner = get_test_runner (sys .stdout ,
55+ verbosity = support .verbose ,
56+ capture_output = (support .junit_xml_list is not None ))
57+
58+ result = runner .run (suite )
59+
60+ if support .junit_xml_list is not None :
61+ support .junit_xml_list .append (result .get_xml_element ())
62+
63+ if not result .testsRun and not result .skipped and not result .errors :
64+ raise support .TestDidNotRun
65+ if not result .wasSuccessful ():
66+ stats = TestStats .from_unittest (result )
67+ if len (result .errors ) == 1 and not result .failures :
68+ err = result .errors [0 ][1 ]
69+ elif len (result .failures ) == 1 and not result .errors :
70+ err = result .failures [0 ][1 ]
71+ else :
72+ err = "multiple errors occurred"
73+ if not verbose : err += "; run in verbose mode for details"
74+ errors = [(str (tc ), exc_str ) for tc , exc_str in result .errors ]
75+ failures = [(str (tc ), exc_str ) for tc , exc_str in result .failures ]
76+ raise support .TestFailedWithDetails (err , errors , failures , stats = stats )
77+ return result
3778
3879
3980def regrtest_runner (result : TestResult , test_func , runtests : RunTests ) -> None :
0 commit comments