summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xLib/test/regrtest.py19
-rw-r--r--Lib/test/support.py22
-rw-r--r--Misc/NEWS5
3 files changed, 40 insertions, 6 deletions
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
index 9bb4307..ef8ea6d 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -43,6 +43,7 @@ Selecting tests
-f/--fromfile -- read names of tests to run from a file (see below)
-x/--exclude -- arguments are tests to *exclude*
-s/--single -- single step through a set of tests (see below)
+-m/--match PAT -- match test cases and methods with glob pattern PAT
-G/--failfast -- fail as soon as a test fails (only with -v or -W)
-u/--use RES1,RES2,...
-- specify which special resource intensive tests to run
@@ -253,7 +254,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
findleaks=False, use_resources=None, trace=False, coverdir='coverage',
runleaks=False, huntrleaks=False, verbose2=False, print_slow=False,
random_seed=None, use_mp=None, verbose3=False, forever=False,
- header=False, failfast=False):
+ header=False, failfast=False, match_tests=None):
"""Execute a test suite.
This also parses command-line options and modifies its behavior
@@ -293,14 +294,14 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
support.record_original_stdout(sys.stdout)
try:
- opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:nj:G',
+ opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:nj:Gm:',
['help', 'verbose', 'verbose2', 'verbose3', 'quiet',
'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks',
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=',
'multiprocess=', 'coverage', 'slaveargs=', 'forever', 'debug',
'start=', 'nowindows', 'header', 'testdir=', 'timeout=', 'wait',
- 'failfast'])
+ 'failfast', 'match'])
except getopt.error as msg:
usage(msg)
@@ -343,6 +344,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
random_seed = int(a)
elif o in ('-f', '--fromfile'):
fromfile = a
+ elif o in ('-m', '--match'):
+ match_tests = a
elif o in ('-l', '--findleaks'):
findleaks = True
elif o in ('-L', '--runleaks'):
@@ -606,7 +609,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
(test, verbose, quiet),
dict(huntrleaks=huntrleaks, use_resources=use_resources,
debug=debug, output_on_failure=verbose3,
- timeout=timeout, failfast=failfast)
+ timeout=timeout, failfast=failfast,
+ match_tests=match_tests)
)
yield (test, args_tuple)
pending = tests_and_args()
@@ -692,7 +696,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
try:
result = runtest(test, verbose, quiet, huntrleaks, debug,
output_on_failure=verbose3,
- timeout=timeout, failfast=failfast)
+ timeout=timeout, failfast=failfast,
+ match_tests=match_tests)
accumulate_result(test, result)
except KeyboardInterrupt:
interrupted = True
@@ -837,7 +842,8 @@ def replace_stdout():
def runtest(test, verbose, quiet,
huntrleaks=False, debug=False, use_resources=None,
- output_on_failure=False, failfast=False, timeout=None):
+ output_on_failure=False, failfast=False, match_tests=None,
+ timeout=None):
"""Run a single test.
test -- the name of the test
@@ -865,6 +871,7 @@ def runtest(test, verbose, quiet,
if use_timeout:
faulthandler.dump_tracebacks_later(timeout, exit=True)
try:
+ support.match_tests = match_tests
if failfast:
support.failfast = True
if output_on_failure:
diff --git a/Lib/test/support.py b/Lib/test/support.py
index 8a60ba9..64c1b4e 100644
--- a/Lib/test/support.py
+++ b/Lib/test/support.py
@@ -21,6 +21,7 @@ import subprocess
import imp
import time
import sysconfig
+import fnmatch
import logging.handlers
try:
@@ -180,6 +181,7 @@ max_memuse = 0 # Disable bigmem tests (they will still be run with
# small sizes, to make sure they work.)
real_max_memuse = 0
failfast = False
+match_tests = None
# _original_stdout is meant to hold stdout at the time regrtest began.
# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
@@ -1268,6 +1270,18 @@ def refcount_test(test):
return no_tracing(cpython_only(test))
+def _filter_suite(suite, pred):
+ """Recursively filter test cases in a suite based on a predicate."""
+ newtests = []
+ for test in suite._tests:
+ if isinstance(test, unittest.TestSuite):
+ _filter_suite(test, pred)
+ newtests.append(test)
+ else:
+ if pred(test):
+ newtests.append(test)
+ suite._tests = newtests
+
def _run_suite(suite):
"""Run tests from a unittest.TestSuite-derived class."""
if verbose:
@@ -1302,6 +1316,14 @@ def run_unittest(*classes):
suite.addTest(cls)
else:
suite.addTest(unittest.makeSuite(cls))
+ def case_pred(test):
+ if match_tests is None:
+ return True
+ for name in test.id().split("."):
+ if fnmatch.fnmatchcase(name, match_tests):
+ return True
+ return False
+ _filter_suite(suite, case_pred)
_run_suite(suite)
diff --git a/Misc/NEWS b/Misc/NEWS
index 0b205ad..5ab2d17 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1137,6 +1137,11 @@ Extension Modules
Tests
-----
+- Issue #12626: In regrtest, allow to filter tests using a glob filter
+ with the ``-m`` (or ``--match``) option. This works with all test cases
+ using the unittest module. This is useful with long test suites
+ such as test_io or test_subprocess.
+
- Issue #12624: It is now possible to fail after the first failure when
running in verbose mode (``-v`` or ``-W``), by using the ``--failfast``
(or ``-G``) option to regrtest. This is useful with long test suites