]> granicus.if.org Git - python/commitdiff
bpo-32071: Fix regression and add What's New entry (#4589)
authorJonas Haag <jonas@lophus.org>
Tue, 28 Nov 2017 19:40:44 +0000 (20:40 +0100)
committerAntoine Pitrou <pitrou@free.fr>
Tue, 28 Nov 2017 19:40:44 +0000 (20:40 +0100)
* bpo-32071: Fix an undocumented behaviour regression

* bpo-32071: Add 3.7 release note entry for unittest -k

Doc/whatsnew/3.7.rst
Lib/unittest/loader.py
Lib/unittest/test/test_loader.py

index a67cbc1576f0e3451b873f7bbb5e6c335069f6aa..4973080eccbf183096e4a5aa2282801407d12f2a 100644 (file)
@@ -398,6 +398,15 @@ Added functions :func:`time.thread_time` and :func:`time.thread_time_ns`
 to get per-thread CPU time measurements.
 (Contributed by Antoine Pitrou in :issue:`32025`.)
 
+
+unittest
+--------
+Added new command-line option ``-k`` to filter tests to run with a substring or
+Unix shell-like pattern.  For example, ``python -m unittest -k foo`` runs the
+tests ``foo_tests.SomeTest.test_something``, ``bar_tests.SomeTest.test_foo``,
+but not ``bar_tests.FooTest.test_something``.
+
+
 unittest.mock
 -------------
 
index eb03b4ab87707a10e84c944b65805c0ef28d9a01..d936a96e73fbc77a8e0e9108ce898010aae3aa6d 100644 (file)
@@ -224,9 +224,10 @@ class TestLoader(object):
         """Return a sorted sequence of method names found within testCaseClass
         """
         def shouldIncludeMethod(attrname):
+            if not attrname.startswith(self.testMethodPrefix):
+                return False
             testFunc = getattr(testCaseClass, attrname)
-            isTestMethod = attrname.startswith(self.testMethodPrefix) and callable(testFunc)
-            if not isTestMethod:
+            if not callable(testFunc):
                 return False
             fullName = '%s.%s' % (testCaseClass.__module__, testFunc.__qualname__)
             return self.testNamePatterns is None or \
index 15b01863f5145457ef90e592d6de192069c24802..bfd722940b5683f2990bcba38ad5740ae93429b2 100644 (file)
@@ -1253,6 +1253,29 @@ class Test_TestLoader(unittest.TestCase):
         loader.testNamePatterns = ['*my*']
         self.assertEqual(loader.getTestCaseNames(MyTest), [])
 
+    # "Return a sorted sequence of method names found within testCaseClass"
+    #
+    # If TestLoader.testNamePatterns is set, only tests that match one of these
+    # patterns should be included.
+    #
+    # For backwards compatibility reasons (see bpo-32071), the check may only
+    # touch a TestCase's attribute if it starts with the test method prefix.
+    def test_getTestCaseNames__testNamePatterns__attribute_access_regression(self):
+        class Trap:
+            def __get__(*ignored):
+                self.fail('Non-test attribute accessed')
+
+        class MyTest(unittest.TestCase):
+            def test_1(self): pass
+            foobar = Trap()
+
+        loader = unittest.TestLoader()
+        self.assertEqual(loader.getTestCaseNames(MyTest), ['test_1'])
+
+        loader = unittest.TestLoader()
+        loader.testNamePatterns = []
+        self.assertEqual(loader.getTestCaseNames(MyTest), [])
+
     ################################################################
     ### /Tests for TestLoader.getTestCaseNames()