bpo-30540, bpo-30523: Add --matchfile and --list-cases options to regrtest (#2249)
[2.7] bpo-30540, bpo-30523: Add --matchfile and --list-cases options to regrtest
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
index 521ac13..3bc3fa6 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -38,6 +38,7 @@
-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
+--matchfile FILENAME -- filters tests using a text file, one pattern per line
-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
@@ -64,6 +65,8 @@
(instead of the Python stdlib test suite)
--list-tests -- only write the name of tests that will be run,
don't execute them
+--list-cases -- only write the name of test cases that will be run,
+ don't execute them
Additional Option Details:
@@ -157,6 +160,13 @@
To enable all resources except one, use '-uall,-<resource>'. For
example, to run all the tests except for the bsddb tests, give the
option '-uall,-bsddb'.
+
+--matchfile filters tests using a text file, one pattern per line.
+Pattern examples:
+
+- test method: test_stat_attributes
+- test class: FileTests
+- test identifier: test_os.FileTests.test_stat_attributes
"""
import StringIO
@@ -316,7 +326,8 @@
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=',
'multiprocess=', 'slaveargs=', 'forever', 'header', 'pgo',
- 'failfast', 'match=', 'testdir=', 'list-tests', 'coverage'])
+ 'failfast', 'match=', 'testdir=', 'list-tests', 'list-cases',
+ 'coverage', 'matchfile='])
except getopt.error, msg:
usage(2, msg)
@@ -327,6 +338,7 @@
use_resources = []
slaveargs = None
list_tests = False
+ list_cases_opt = False
for o, a in opts:
if o in ('-h', '--help'):
usage(0)
@@ -354,7 +366,16 @@
elif o in ('-f', '--fromfile'):
fromfile = a
elif o in ('-m', '--match'):
- match_tests = a
+ if match_tests is None:
+ match_tests = []
+ match_tests.append(a)
+ elif o == '--matchfile':
+ if match_tests is None:
+ match_tests = []
+ filename = os.path.join(test_support.SAVEDCWD, a)
+ with open(filename) as fp:
+ for line in fp:
+ match_tests.append(line.strip())
elif o in ('-l', '--findleaks'):
findleaks = True
elif o in ('-L', '--runleaks'):
@@ -416,6 +437,8 @@
testdir = a
elif o == '--list-tests':
list_tests = True
+ elif o == '--list-cases':
+ list_cases_opt = True
else:
print >>sys.stderr, ("No handler for option {}. Please "
"report this as a bug at http://bugs.python.org.").format(o)
@@ -534,6 +557,10 @@
print(name)
sys.exit(0)
+ if list_cases_opt:
+ list_cases(testdir, selected)
+ sys.exit(0)
+
if trace:
import trace
tracer = trace.Trace(trace=False, count=True)
@@ -1124,11 +1151,7 @@
try:
if capture_stdout:
sys.stdout = capture_stdout
- if test.startswith('test.') or testdir:
- abstest = test
- else:
- # Always import it from the test package
- abstest = 'test.' + test
+ abstest = get_abs_module(testdir, test)
clear_caches()
with saved_test_environment(test, verbose, quiet, pgo) as environment:
start_time = time.time()
@@ -1452,7 +1475,7 @@
else:
return "%d %ss" % (n, word)
-def printlist(x, width=70, indent=4):
+def printlist(x, width=70, indent=4, file=None):
"""Print the elements of iterable x to stdout.
Optional arg width (default 70) is the maximum line length.
@@ -1463,8 +1486,37 @@
from textwrap import fill
blanks = ' ' * indent
# Print the sorted list: 'x' may be a '--random' list or a set()
- print fill(' '.join(str(elt) for elt in sorted(x)), width,
- initial_indent=blanks, subsequent_indent=blanks)
+ print >>file, fill(' '.join(str(elt) for elt in sorted(x)), width,
+ initial_indent=blanks, subsequent_indent=blanks)
+
+def get_abs_module(testdir, test):
+ if test.startswith('test.') or testdir:
+ return test
+ else:
+ # Always import it from the test package
+ return 'test.' + test
+
+def _list_cases(suite):
+ for test in suite:
+ if isinstance(test, unittest.TestSuite):
+ _list_cases(test)
+ elif isinstance(test, unittest.TestCase):
+ print(test.id())
+
+def list_cases(testdir, selected):
+ skipped = []
+ for test in selected:
+ abstest = get_abs_module(testdir, test)
+ try:
+ suite = unittest.defaultTestLoader.loadTestsFromName(abstest)
+ _list_cases(suite)
+ except unittest.SkipTest:
+ skipped.append(test)
+
+ if skipped:
+ print >>sys.stderr
+ print >>sys.stderr, count(len(skipped), "test"), "skipped:"
+ printlist(skipped, file=sys.stderr)
# Map sys.platform to a string containing the basenames of tests
# expected to be skipped on that platform.