bpo-30540: regrtest: add --matchfile option (#1909)

* Add a new option taking a filename to get a list of test names to
  filter tests.
* support.match_tests becomes a list.
* Modify run_unittest() to accept to match the whole test identifier,
  not just a part of a test identifier.

For example, the following command only runs test_default_timeout()
of the BarrierTests class of test_threading:

$ ./python -m test -v test_threading -m test.test_threading.BarrierTests.test_default_timeout

Remove also some empty lines from test_regrtest.py to make flake8
tool happy.
This commit is contained in:
Victor Stinner 2017-06-09 10:18:48 +02:00 committed by GitHub
parent 824f687912
commit ef8320cf6f
3 changed files with 89 additions and 6 deletions

View file

@ -159,9 +159,24 @@ class ParseArgsTestCase(unittest.TestCase):
for opt in '-m', '--match':
with self.subTest(opt=opt):
ns = libregrtest._parse_args([opt, 'pattern'])
self.assertEqual(ns.match_tests, 'pattern')
self.assertEqual(ns.match_tests, ['pattern'])
self.checkError([opt], 'expected one argument')
ns = libregrtest._parse_args(['-m', 'pattern1',
'-m', 'pattern2'])
self.assertEqual(ns.match_tests, ['pattern1', 'pattern2'])
self.addCleanup(support.unlink, support.TESTFN)
with open(support.TESTFN, "w") as fp:
print('matchfile1', file=fp)
print('matchfile2', file=fp)
filename = os.path.abspath(support.TESTFN)
ns = libregrtest._parse_args(['-m', 'match',
'--matchfile', filename])
self.assertEqual(ns.match_tests,
['match', 'matchfile1', 'matchfile2'])
def test_failfast(self):
for opt in '-G', '--failfast':
with self.subTest(opt=opt):
@ -275,7 +290,6 @@ class ParseArgsTestCase(unittest.TestCase):
ns = libregrtest._parse_args([opt])
self.assertTrue(ns.forever)
def test_unrecognized_argument(self):
self.checkError(['--xxx'], 'usage:')
@ -457,7 +471,6 @@ class BaseTestCase(unittest.TestCase):
self.fail(msg)
return proc
def run_python(self, args, **kw):
args = [sys.executable, '-X', 'faulthandler', '-I', *args]
proc = self.run_command(args, **kw)
@ -823,6 +836,52 @@ class ArgsTestCase(BaseTestCase):
self.check_executed_tests(output, tests, failed=crash_test,
randomize=True)
def parse_methods(self, output):
regex = re.compile("^(test[^ ]+).*ok$", flags=re.MULTILINE)
return [match.group(1) for match in regex.finditer(output)]
def test_matchfile(self):
# Any code which causes a crash
code = textwrap.dedent("""
import unittest
class Tests(unittest.TestCase):
def test_method1(self):
pass
def test_method2(self):
pass
def test_method3(self):
pass
def test_method4(self):
pass
""")
all_methods = ['test_method1', 'test_method2',
'test_method3', 'test_method4']
testname = self.create_test(code=code)
# by default, all methods should be run
output = self.run_tests("-v", testname)
methods = self.parse_methods(output)
self.assertEqual(methods, all_methods)
# only run a subset
filename = support.TESTFN
self.addCleanup(support.unlink, filename)
subset = [
# only match the method name
'test_method1',
# match the full identifier
'%s.Tests.test_method3' % testname]
with open(filename, "w") as fp:
for name in subset:
print(name, file=fp)
output = self.run_tests("-v", "--matchfile", filename, testname)
methods = self.parse_methods(output)
subset = ['test_method1', 'test_method3']
self.assertEqual(methods, subset)
if __name__ == '__main__':
unittest.main()