formicaman
formicaman

Reputation: 1357

How to use pytest on script with no functions

Let's say I have a Python script like this:

import pandas

df = pd.read_csv('____')
if len(df) > 5:
    print('small df')
else:
    print('large df')

Or any script that doesn't have functions. Can I use pytest or any other library to get a coverage xml? All the examples I have seen are for functions.

Upvotes: 2

Views: 444

Answers (1)

Lars Blumberg
Lars Blumberg

Reputation: 21381

You can measure coverage of modules with globally executed code using the following files (I've simplified your above example a bit, you can however install panda as well).

Since I'd like to run Python code within Docker containers, I'm listing all files involved for a minimal setup. After you've place all files within a (new) folder, you can print the test coverage using the command

make test-cov

Makefile

IMAGE_NAME := python-test-cov

build:
    docker build -t ${IMAGE_NAME} .

test: build
    docker run -t ${IMAGE_NAME} bash -c "python -m pytest -vv"

test-cov: build
    docker run -t ${IMAGE_NAME} bash -c \
      "coverage run --source main -m pytest && coverage report --show-missing"

Dockerfile

FROM python:3.9-slim-buster
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py test_main.py ./
CMD python3 main.py

main.py

array = [1, 2, 3]

if len(array) < 5:
    print('small array')
else:
    print('large array')

test_main.py

def test_main(capfd):
    import main
    out, err = capfd.readouterr()
    assert out == "small array\n"

requirements.txt

coverage==5.1
pytest==6.1.2

As mentioned above, run make test-cov in the same folder as where the files are stored to print the test coverage.

The output should be the following, indicating that line 6 of main.py is not covered:

> make test-cov

============================ test session starts =============================
platform linux -- Python 3.9.4, pytest-6.1.2, py-1.10.0, pluggy-0.13.1
rootdir: /app
collected 1 item                                                             

test_main.py .                                                         [100%]

============================= 1 passed in 0.04s ==============================
Name      Stmts   Miss  Cover   Missing
---------------------------------------
main.py       4      1    75%   6


PS: Even if bad practice, if you want to run above example without Docker and install all modules globally, then just place main.py and test_main.py in a folder of your choice and run these commands in the same folder:

pip3 install coverage==5.1 pytest==6.1.2
coverage run --source main -m pytest && coverage report --show-missing

You should get the same result as above.

Upvotes: 3

Related Questions