Search code examples
pythonpytestcoverage.pypytest-cov

pytest-cov plugin reports imports and function definitions not being covered by tests


I am using pytest coverage and following I have the tests scripts in the command line that will generate the coverage reports for me:

"""Manager script to run the commands on the Flask API."""
import os
import click
from api import create_app
from briqy.logHelper import b as logger
import pytest

app = create_app()


@app.cli.command("tests")
@click.argument("option", required=False)
def run_test_with_option(option: str = None):
    from subprocess import run
    from shlex import split

    if option is None:
        raise SystemExit(
            pytest.main(
                [
                    "--disable-pytest-warnings",
                    "--cov=lib",
                    "--cov-config=.coveragerc",
                    "--cov-report=term",
                    "--cov-report=xml",
                    "--cov-report=html",
                    "--junitxml=./tests/coverage/junit.xml",
                    "--cov-append",
                    "--no-cov-on-fail",
                ]
            )
        )
    elif option == "watch":
        run(
            split(
                'ptw --runner "python3 -m pytest tests --durations=5 '
                '--disable-pytest-warnings"'
            )
        )
    elif option == "debug":
        run(
            split(
                'ptw --pdb --runner "python3 -m pytest tests --durations=5 '
                '--disable-pytest-warnings"'
            )
        )


if __name__ == "__main__":
    HOST = os.getenv("FLASK_RUN_HOST", default="127.0.0.1")
    PORT = os.getenv("FLASK_RUN_PORT", default=5000)
    DEBUG = os.getenv("FLASK_DEBUG", default=False)

    app.run(
        host=HOST,
        port=PORT,
        debug=DEBUG,
    )

    if bool(DEBUG):
        logger.info(f"Flask server is running in {os.getenv('ENV')}")

However, after running the tests, it shows the imports on top of the file being uncovered by tests. Does anyone know how to get rid of those uncovered lines?


Solution

  • You haven't shown the whole program, but I will guess that you are importing your product code at the top of this file. That means all of the top-level statements in the product code (import, class, def, etc) will have already run by the time the pytest-cov plugin starts the coverage measurement.

    There are a few things you can do:

    1. Run pytest from the command line instead of in-process in your product code.
    2. Change this code to start pytest in a subprocess so that everything will be re-imported by pytest.

    What you should not do: exclude import lines from coverage measurement. The .coveragerc you showed will ignore any line with the string "from" or "import" in it, which isn't what you want ("import" is in "do_important_thing()" for example!)