From 0876ac71553847cab544e495875cd89f65bbc232 Mon Sep 17 00:00:00 2001 From: Frederic Leger Date: Tue, 14 May 2024 11:49:07 +0200 Subject: [PATCH] Fix pytest when source coverage is not used The source coverage option may not be defined when running the tests manually. The option existence should be checked before trying to get it. Closes #720 --- pyproject.toml | 4 ++++ src/e3/pytest.py | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 63805203..04f96ee9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,9 @@ classifiers = [ "Topic :: Software Development :: Build Tools" ] +# Even if they are used by the pytest driver, the pytest and coverage +# dependencies are not installed by default. This is on purpose to avoid +# importing test/coverage packages in a release install. dependencies = [ "colorama", "pyyaml", @@ -49,6 +52,7 @@ config = [ "typeguard<3.0.0" ] test = [ + "coverage", "mock", "requests-mock", "pytest", diff --git a/src/e3/pytest.py b/src/e3/pytest.py index 574b1fe2..9b1566ea 100644 --- a/src/e3/pytest.py +++ b/src/e3/pytest.py @@ -12,19 +12,26 @@ import e3.log -from coverage.sqldata import CoverageData -from coverage.files import PathAliases -from coverage import Coverage - - -import pytest +try: + import pytest + from coverage.sqldata import CoverageData + from coverage.files import PathAliases + from coverage import Coverage +except ImportError as ie: + # Those packages may be missing. In order to avoid importing tests or + # coverage packages in release mode, they are deliberately not part of + # the dependencies. Let the user know that the packages should be installed + # if he wants to use e3 pytest driver. + raise ImportError( + "Missing test and coverage packages. Please install pytest and coverage " + "packages" + ) from ie import typing if typing.TYPE_CHECKING: from typing import Callable - test_errors = False # Detect that we're in CI mode, most providers set the $CI environment variable @@ -73,7 +80,7 @@ def env_protect(request: pytest.FixtureRequest) -> None: The fixture is enabled for all tests and does the following: - * store/restore env between each tests + * store/restore env between tests * create a temporary directory and do a cd to it before each test. The directory is automatically removed when test ends """ @@ -98,9 +105,13 @@ def restore_env() -> None: def pytest_configure(config: pytest.Config) -> None: - if config.getoption("e3") and config.getoption("cov_source"): + if ( + config.getoption("e3") + and hasattr(config.option, "cov_source") + and config.getoption("cov_source") + ): # When e3 plugin is activated, the report generated by pytest-cov - # should be deactivated to avoid duplicating the output. Also + # should be deactivated to avoid duplicating the output. Also, # some options set by e3 change the coverage, pytest-cov report is not # accurate in that case. cov = config.pluginmanager.getplugin("_cov") @@ -122,9 +133,13 @@ def pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> None: # test code. session.exitstatus = 3 - if session.config.getoption("cov_source"): + if hasattr(session.config.option, "cov_source") and session.config.getoption( + "cov_source" + ): cov_file = str(session.config.rootpath / ".coverage") - if session.config.getoption("e3_cov_rewrite"): + if hasattr( + session.config.option, "e3_cov_rewrite" + ) and session.config.getoption("e3_cov_rewrite"): origin_dir, new_dir = session.config.getoption("e3_cov_rewrite") fix_coverage_paths(origin_dir=origin_dir, new_dir=new_dir, cov_db=cov_file) @@ -181,7 +196,7 @@ def fix_coverage_paths(origin_dir: str, new_dir: str, cov_db: str) -> None: .tox/py311-cov-xdist/lib/python3.11/site-packages/e3 :param new_dir: path to the dir that should be visible instead of origin_dir e.g. src/ - :param cov_db: path to the .coverage data base + :param cov_db: path to the .coverage database """ paths = PathAliases() paths.add(origin_dir, new_dir)