Как получить отчет о покрытии при тестировании плагина pytest?

Контекст

Я обновляю унаследованный репозиторий с плохим тестовым покрытием. Само репо - это плагин pytest. Я изменил репозиторий, чтобы использовать tox вместе с pytest-cov, и преобразовал необработанные тесты для использования pytester, как это было предложено в документации pytest при тестировании подключаемых модулей.

Тестирование, сборка tox и т. Д. Отлично работает. Однако покрытие сообщает о ложных промахах с такими вещами, как определения классов, импорт и т. Д. Это связано с тем, что сам код импортируется как часть создания экземпляра pytest и не покрывается до тех пор, пока фактически не начнется тестирование.

Я читал документы pytest, pytest-cov и охват, а также документы tox, пробовал несколько конфигураций, но безрезультатно. Я исчерпал свой набор комбинаций ключевых слов Google, которые могут привести меня к хорошему решению.

Макет репозитория

pkg_root/
    .tox/
        py3/
            lib/
                python3.7/
                    site-pacakges/
                        plugin_module/
                            supporting_module.py
                            plugin.py
                            some_data.dat
    plugin_module/
        supporting_module.py
        plugin.py
        some_data.dat
    tests/
        conftest.py
        test_my_plugin.py
    tox.ini
    setup.py
    

Некоторые релевантные фрагменты с комментариями:

tox.ini

[pytest]
addopts = --cov={envsitepackagesdir}/plugin_module --cov-report=html
testpaths = tests

Эта конфигурация дает мне ошибку, что данные не были собраны; в этом случае htmlcov не создается.

Если я просто использую --cov, я получаю (ожидаемое) очень шумное покрытие, которое показывает функциональные попадания и промахи, но с ложными промахами, указанными выше для импорта, определений классов и т. Д.

conftest.py

pytest_plugins = ['pytester']  # Entire contents of file!

test_my_plugin.py

def test_a_thing(testdir):
    testdir.makepyfile(
        """
            def test_that_fixture(my_fixture):
                assert my_fixture.foo == 'bar'
        """
    )
    result = testdir.runpytest()
    result.assert_outcomes(passed=1)

Как я могу получить точный отчет? Есть ли способ отложить загрузку плагина до тех пор, пока этого не потребуют тесты pytester?


person Thomas Thorogood    schedule 05.06.2020    source источник


Ответы (2)


Вместо использования плагина pytest-cov используйте покрытие для запуска pytest:

coverage run -m pytest ....

Таким образом, покрытие будет запущено до pytest.

person Ned Batchelder    schedule 05.06.2020
comment
Ой ну спасибо. Я немного разберусь с этим. Это не сработало из коробки, но звучит как гораздо лучшее решение, чем мое собственное (stackoverflow.com/a/62224965/ 677283), так что, наверное, стоит разобраться. - person Thomas Thorogood; 06.06.2020
comment
Да, удаляю свой ответ. Это ужасно и очень хрупко, и наносит ущерб многим вещам! На следующей неделе я потрачу больше времени и постараюсь заставить все работать таким образом. - person Thomas Thorogood; 06.06.2020
comment
Да, мне удалось заставить это работать с commands = coverage run --source=plugin_module -m pytest - person Thomas Thorogood; 06.06.2020
comment
Это создает .coverage файл базы данных SQLite, который можно прочитать с помощью coverage report. - person Cees Timmerman; 23.12.2020

Вы можете добиться желаемого без pytest-cov.


❯ coverage run --source=<package> --module pytest --verbose <test-files-dirs> && coverage report --show-missing
OR SHORTER
❯ coverage run --source=<package> -m pytest -v <test-files-dirs> && coverage report -m
Пример: (для вашей структуры каталогов)
❯ coverage run --source=plugin_module -m pytest -v tests && coverage report -m
======================= test session starts ========================
platform darwin -- Python 3.9.4, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- /Users/johndoe/.local/share/virtualenvs/plugin_module--WYTJL20/bin/python
cachedir: .pytest_cache
rootdir: /Users/johndoe/projects/plugin_module, configfile: pytest.ini
collected 1 items

tests/test_my_plugin.py::test_my_plugin PASSED               [100%]

======================== 1 passed in 0.04s =========================
Name                            Stmts   Miss  Cover   Missing
-------------------------------------------------------------
plugin_module/supporting_module.py  4      0   100%
plugin_module/plugin.py             6      0   100%
-------------------------------------------------------------
TOTAL                              21      0   100%

Для еще лучшего результата вы можете использовать:

❯ coverage html && open htmlcov/index.html

HTML-отчет о покрытии


Документация

❯ coverage -h
❯ pytest -h

coverage

run - Запустить программу Python и измерить выполнение кода.

-m, --module --- Показать номера строк операторов в каждом модуле, которые не были выполнены.

--source=SRC1,SRC2, --- Список пакетов или каталогов кода для измерения.

report - Сообщать статистику покрытия по модулям.

-m, --show-missing --- Показать номера строк операторов в каждом модуле, которые не были выполнены.

html - Создать отчет в формате HTML.

pytest

-v, --verbose - повысить многословность.

person Akharrou    schedule 15.06.2021