[Python-checkins] cpython (merge 3.2 -> default): Issue #12626: In regrtest, allow to filter tests using a glob filter

antoine.pitrou python-checkins at python.org
Fri Jul 29 23:58:54 CEST 2011


http://hg.python.org/cpython/rev/018e14a46454
changeset:   71613:018e14a46454
parent:      71611:a6afd26caa8a
parent:      71612:5d7a2bd9a3d1
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Fri Jul 29 23:57:10 2011 +0200
summary:
  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.

files:
  Lib/test/regrtest.py |  19 +++++++++++++------
  Lib/test/support.py  |  22 ++++++++++++++++++++++
  Misc/NEWS            |   5 +++++
  3 files changed, 40 insertions(+), 6 deletions(-)


diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -43,6 +43,7 @@
 -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 @@
          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 @@
 
     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 @@
             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 @@
                     (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 @@
                 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 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 @@
     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
--- a/Lib/test/support.py
+++ b/Lib/test/support.py
@@ -21,6 +21,7 @@
 import imp
 import time
 import sysconfig
+import fnmatch
 import logging.handlers
 
 try:
@@ -180,6 +181,7 @@
                          # 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 @@
     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 @@
             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
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1137,6 +1137,11 @@
 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

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list