| # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 |
| # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt |
| |
| """ |
| Pytest auto configuration. |
| |
| This module is run automatically by pytest, to define and enable fixtures. |
| """ |
| |
| from __future__ import annotations |
| |
| import os |
| import sys |
| import warnings |
| |
| from collections.abc import Iterable |
| |
| import pytest |
| |
| from coverage.files import set_relative_directory |
| from coverage.patch import create_pth_files |
| |
| |
| # Pytest will rewrite assertions in test modules, but not elsewhere. |
| # This tells pytest to also rewrite assertions in these files: |
| pytest.register_assert_rewrite("tests.coveragetest") |
| pytest.register_assert_rewrite("tests.helpers") |
| |
| # Pytest can take additional options: |
| # $set_env.py: PYTEST_ADDOPTS - Extra arguments to pytest. |
| |
| pytest_plugins = [ |
| "tests.select_plugin", |
| ] |
| |
| |
| @pytest.fixture(autouse=True) |
| def set_warnings() -> None: |
| """Configure warnings to show while running tests.""" |
| warnings.simplefilter("default") |
| warnings.simplefilter("once", DeprecationWarning) |
| |
| # Warnings to suppress: |
| # How come these warnings are successfully suppressed here, but not in pyproject.toml?? |
| |
| # Note: when writing the regex for the message, it's matched with re.match, |
| # so it has to match the beginning of the message. Add ".*" to make it |
| # match something in the middle of the message. |
| |
| # Don't warn about unclosed SQLite connections. |
| # We don't close ":memory:" databases because we don't have a way to connect |
| # to them more than once if we close them. In real coverage.py uses, there |
| # are only a couple of them, but our test suite makes many and we get warned |
| # about them all. |
| # Python3.13 added this warning, but the behavior has been the same all along, |
| # without any reported problems, so just quiet the warning. |
| # https://github.com/python/cpython/issues/105539 |
| warnings.filterwarnings("ignore", r"unclosed database", category=ResourceWarning) |
| |
| # We have a test that has a return in a finally: test_bug_1891. |
| warnings.filterwarnings("ignore", "'return' in a 'finally' block", category=SyntaxWarning) |
| |
| |
| @pytest.fixture(autouse=True) |
| def reset_sys_path() -> Iterable[None]: |
| """Clean up sys.path changes around every test.""" |
| sys_path = list(sys.path) |
| yield |
| sys.path[:] = sys_path |
| |
| |
| @pytest.fixture(autouse=True) |
| def reset_environment() -> Iterable[None]: |
| """Make sure a test setting an envvar doesn't leak into another test.""" |
| old_environ = os.environ.copy() |
| yield |
| os.environ.clear() |
| os.environ.update(old_environ) |
| |
| |
| @pytest.fixture(autouse=True) |
| def reset_filesdotpy_globals() -> None: |
| """coverage/files.py has some unfortunate globals. Reset them every test.""" |
| set_relative_directory() |
| |
| |
| @pytest.fixture(autouse=True) |
| def force_local_pyc_files() -> None: |
| """Ensure that .pyc files are written next to source files.""" |
| # For some tests, we need .pyc files written in the current directory, |
| # so override any local setting. |
| sys.pycache_prefix = None |
| |
| |
| # Give this an underscored name so pylint won't complain when we use the fixture. |
| @pytest.fixture(name="_create_pth_file") |
| def create_pth_file_fixture() -> Iterable[None]: |
| """Create and clean up a .pth file for tests that need it for subprocesses.""" |
| pth_files = create_pth_files() |
| try: |
| yield |
| finally: |
| for p in pth_files: |
| p.unlink() |
| |
| |
| @pytest.hookimpl(wrapper=True) |
| def pytest_runtest_call() -> Iterable[None]: |
| """Check the exception raised by the test, and skip the test if needed.""" |
| try: |
| yield |
| except Exception as e: # pragma: never metacov |
| # This code is for dealing with the exception raised when we are |
| # measuring with a core that doesn't support branch measurement. |
| # During metacov, we skip those situations entirely by not running |
| # sysmon on 3.12 or 3.13, so this code is never needed during metacov. |
| if getattr(e, "skip_tests", False): |
| pytest.skip(f"Skipping for exception: {e}") |
| else: |
| raise |