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)