Optional tests are markers. Use the syntax in https://docs.pytest.org/en/stable/mark.html#registering-marks.
(config: "Config")
| 55 | |
| 56 | |
| 57 | def pytest_configure(config: "Config") -> None: |
| 58 | """Optional tests are markers. |
| 59 | |
| 60 | Use the syntax in https://docs.pytest.org/en/stable/mark.html#registering-marks. |
| 61 | """ |
| 62 | ot_ini = config.inicfg.get("optional-tests") or [] |
| 63 | ot_markers = set() |
| 64 | ot_run: Set[str] = set() |
| 65 | if isinstance(ot_ini, str): |
| 66 | ot_ini = ot_ini.strip().split("\n") |
| 67 | marker_re = re.compile(r"^\s*(?P<no>no_)?(?P<marker>\w+)(:\s*(?P<description>.*))?") |
| 68 | for ot in ot_ini: |
| 69 | m = marker_re.match(ot) |
| 70 | if not m: |
| 71 | raise ValueError(f"{ot!r} doesn't match pytest marker syntax") |
| 72 | |
| 73 | marker = (m.group("no") or "") + m.group("marker") |
| 74 | description = m.group("description") |
| 75 | config.addinivalue_line("markers", f"{marker}: {description}") |
| 76 | config.addinivalue_line( |
| 77 | "markers", f"{no(marker)}: run when `{marker}` not passed" |
| 78 | ) |
| 79 | ot_markers.add(marker) |
| 80 | |
| 81 | # collect requested optional tests |
| 82 | passed_args = config.getoption("run_optional") |
| 83 | if passed_args: |
| 84 | ot_run.update(itertools.chain.from_iterable(a.split(",") for a in passed_args)) |
| 85 | ot_run |= {no(excluded) for excluded in ot_markers - ot_run} |
| 86 | ot_markers |= {no(m) for m in ot_markers} |
| 87 | |
| 88 | log.info("optional tests to run:", ot_run) |
| 89 | unknown_tests = ot_run - ot_markers |
| 90 | if unknown_tests: |
| 91 | raise ValueError(f"Unknown optional tests wanted: {unknown_tests!r}") |
| 92 | |
| 93 | store = config._store |
| 94 | store[ALL_POSSIBLE_OPTIONAL_MARKERS] = frozenset(ot_markers) |
| 95 | store[ENABLED_OPTIONAL_MARKERS] = frozenset(ot_run) |
| 96 | |
| 97 | |
| 98 | def pytest_collection_modifyitems(config: "Config", items: "List[Node]") -> None: |