• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import os
2import sys
3import unittest
4
5from test import support
6
7from .filter import match_test, set_match_tests
8from .utils import (
9    StrPath, TestName, TestTuple, TestList, TestFilter,
10    abs_module_name, count, printlist)
11
12
13# If these test directories are encountered recurse into them and treat each
14# "test_*.py" file or each sub-directory as a separate test module. This can
15# increase parallelism.
16#
17# Beware this can't generally be done for any directory with sub-tests as the
18# __init__.py may do things which alter what tests are to be run.
19SPLITTESTDIRS: set[TestName] = {
20    "test_asyncio",
21    "test_concurrent_futures",
22    "test_doctests",
23    "test_future_stmt",
24    "test_gdb",
25    "test_inspect",
26    "test_pydoc",
27    "test_multiprocessing_fork",
28    "test_multiprocessing_forkserver",
29    "test_multiprocessing_spawn",
30}
31
32
33def findtestdir(path: StrPath | None = None) -> StrPath:
34    return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir
35
36
37def findtests(*, testdir: StrPath | None = None, exclude=(),
38              split_test_dirs: set[TestName] = SPLITTESTDIRS,
39              base_mod: str = "") -> TestList:
40    """Return a list of all applicable test modules."""
41    testdir = findtestdir(testdir)
42    tests = []
43    for name in os.listdir(testdir):
44        mod, ext = os.path.splitext(name)
45        if (not mod.startswith("test_")) or (mod in exclude):
46            continue
47        if base_mod:
48            fullname = f"{base_mod}.{mod}"
49        else:
50            fullname = mod
51        if fullname in split_test_dirs:
52            subdir = os.path.join(testdir, mod)
53            if not base_mod:
54                fullname = f"test.{mod}"
55            tests.extend(findtests(testdir=subdir, exclude=exclude,
56                                   split_test_dirs=split_test_dirs,
57                                   base_mod=fullname))
58        elif ext in (".py", ""):
59            tests.append(fullname)
60    return sorted(tests)
61
62
63def split_test_packages(tests, *, testdir: StrPath | None = None, exclude=(),
64                        split_test_dirs=SPLITTESTDIRS):
65    testdir = findtestdir(testdir)
66    splitted = []
67    for name in tests:
68        if name in split_test_dirs:
69            subdir = os.path.join(testdir, name)
70            splitted.extend(findtests(testdir=subdir, exclude=exclude,
71                                      split_test_dirs=split_test_dirs,
72                                      base_mod=name))
73        else:
74            splitted.append(name)
75    return splitted
76
77
78def _list_cases(suite):
79    for test in suite:
80        if isinstance(test, unittest.loader._FailedTest):
81            continue
82        if isinstance(test, unittest.TestSuite):
83            _list_cases(test)
84        elif isinstance(test, unittest.TestCase):
85            if match_test(test):
86                print(test.id())
87
88def list_cases(tests: TestTuple, *,
89               match_tests: TestFilter | None = None,
90               test_dir: StrPath | None = None):
91    support.verbose = False
92    set_match_tests(match_tests)
93
94    skipped = []
95    for test_name in tests:
96        module_name = abs_module_name(test_name, test_dir)
97        try:
98            suite = unittest.defaultTestLoader.loadTestsFromName(module_name)
99            _list_cases(suite)
100        except unittest.SkipTest:
101            skipped.append(test_name)
102
103    if skipped:
104        sys.stdout.flush()
105        stderr = sys.stderr
106        print(file=stderr)
107        print(count(len(skipped), "test"), "skipped:", file=stderr)
108        printlist(skipped, file=stderr)
109