diff options
-rw-r--r-- | Doc/whatsnew/3.7.rst | 9 | ||||
-rw-r--r-- | Lib/unittest/loader.py | 5 | ||||
-rw-r--r-- | Lib/unittest/test/test_loader.py | 23 |
3 files changed, 35 insertions, 2 deletions
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index a67cbc1576..4973080ecc 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -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 ------------- diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py index eb03b4ab87..d936a96e73 100644 --- a/Lib/unittest/loader.py +++ b/Lib/unittest/loader.py @@ -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 \ diff --git a/Lib/unittest/test/test_loader.py b/Lib/unittest/test/test_loader.py index 15b01863f5..bfd722940b 100644 --- a/Lib/unittest/test/test_loader.py +++ b/Lib/unittest/test/test_loader.py @@ -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() |