Подтвердить что ты не робот

Использование py.test с охватом не включает импорт

Для Jedi мы хотим сгенерировать наше тестовое покрытие. В stackoverflow есть связанный вопрос, но это не помогло.

Мы используем py.test как тестовый бегун. Однако мы не можем добавить импорт и другие "импортированные" материалы в отчет. Например, __init__.py всегда сообщается как непокрытый:

Name                           Stmts   Miss  Cover
--------------------------------------------------
jedi/__init__                      5      5     0%
[..]

Очевидно, что этот файл импортируется и поэтому должен быть сообщен как проверенный.

Мы запускаем тесты, подобные этому [*]:

py.test --cov jedi

Как вы можете видеть, мы используем pytest-coverage.

Итак, как можно правильно подсчитать покрытие файлов, таких как __init__.py?

[*] Мы также попробовали запустить тест без --doctest-modules (удален из pytest.ini) и активировать модуль покрытия раньше py.test -p pytest_cov --cov jedi. Ни один из них не работает.

Я предложил щедрость. Попробуйте исправить это в рамках джедая. Это общедоступно.

4b9b3361

Ответ 1

@hynekcer дал мне правильную идею. Но в основном самое простое решение лежит где-то в другом месте:

Избавиться от pytest-cov!

Использование

coverage run --source jedi -m py.test
coverage report

вместо!!! Таким образом, вы просто используете покрытие вашей текущей конфигурации py.test, которая работает отлично! Это также философски правильный путь: сделать каждую программу хорошо - py.test запускает тесты и coverage проверяет охват кода.

Теперь это может звучать как напыщенная речь, но на самом деле. pytest-cov работает некорректно. Некоторые тесты были неудачными, только потому, что мы использовали его.


По состоянию на 2014, pytest-cov, похоже, сменил руки. py.test --cov jedi test снова кажется полезной командой (посмотрите на комментарии). Однако вам не нужно его использовать. Но в сочетании с xdist он может ускорить ваши отчеты о покрытии.

Ответ 2

Я установил покрытие теста на 94% на этот патч, который упрощает импортные зависимости и по команде:

py.test --cov jedi test                    # or
py.test --cov jedi test --cov-report=html  # + a listing with red uncovered lines

Непокрытые строки находятся только в условных командах или в некоторых менее используемых функциях, но все заголовки полностью закрыты.

Проблема заключалась в том, что конфигурация тестов test/conftest.py преждевременно импортировала зависимости почти всех файлов в проекте. Файл conftest определяет также дополнительные параметры командной строки и параметры, которые должны быть установлены перед запуском теста. Поэтому я думаю, что плагин pytest_cov работает правильно, если он игнорирует все, что было импортировано вместе с этим файлом, хотя это боль. Я исключил также __init__.py и settings.py из отчета, потому что они просты и с полным охватом, но они также могут быть импортированы преждевременно в зависимости от conftest.

Ответ 3

В моем случае все тесты выполнялись, но охват составлял 0%.

Исправление было:

$ export PYTHONPATH="."

После правильного результата.

В прошлых нескольких проблемах с командой py.test возникли проблемы с импортом, а решение PYTHONPATH env var было решением. Это тоже помогло мне на этот раз.

Мой реальный пример с awslogs

Сначала PYTHONPATH unset:

$ py.test --cov=awslogs  tests/
========================================= test session starts =========================================
platform linux2 -- Python 2.7.9, pytest-2.8.5, py-1.4.31, pluggy-0.3.1
rootdir: /home/javl/sandbox/awslogs/github/awslogs, inifile:
plugins: cov-2.2.0
collected 11 items

tests/test_it.py ...........Coverage.py warning: No data was collected.

--------------------------- coverage: platform linux2, python 2.7.9-final-0 ---------------------------
Name                    Stmts   Miss  Cover
-------------------------------------------
awslogs/__init__.py         2      2     0%
awslogs/bin.py             85     85     0%
awslogs/core.py           143    143     0%
awslogs/exceptions.py      12     12     0%
-------------------------------------------
TOTAL                     242    242     0%

====================================== 11 passed in 0.38 seconds ======================================

Результирующее покрытие составляет 0%.

Затем я устанавливаю PYTHONPATH:

$ export PYTHONPATH="."

и повторите тест:

$ py.test --cov=awslogs  tests/
========================================= test session starts =========================================
platform linux2 -- Python 2.7.9, pytest-2.8.5, py-1.4.31, pluggy-0.3.1
rootdir: /home/javl/sandbox/awslogs/github/awslogs, inifile:
plugins: cov-2.2.0
collected 11 items

tests/test_it.py ...........
--------------------------- coverage: platform linux2, python 2.7.9-final-0 ---------------------------
Name                    Stmts   Miss  Cover
-------------------------------------------
awslogs/__init__.py         2      0   100%
awslogs/bin.py             85      9    89%
awslogs/core.py           143     12    92%
awslogs/exceptions.py      12      2    83%
-------------------------------------------
TOTAL                     242     23    90%

====================================== 11 passed in 0.44 seconds ======================================

Теперь охват 90%.

ПРЕДУПРЕЖДЕНИЕ: манипулирование PYTHONPATH может иметь странные побочные эффекты. В настоящее время я столкнулся с проблемой, что pbr основанный пакет создает каталог яйца при создании дистрибутива, а если PYTHONPATH установлен в ".", Он автоматически рассматривает пакет, связанный с яйцом, как он был установлен. По этой причине я прекратил использовать pytest-cov и следую рекомендациям использовать инструмент coverage.

Ответ 4

У меня была эта проблема с py.test, охватом и плагином django. По-видимому, файлы модели импортируются до начала запуска. Даже "-p-охват" для ранней загрузки плагина-плагина не работал.

Я исправил это (уродливое?), удалив модуль моделей из sys.modules и повторно импортировав его в тестовый файл, который тестирует модель:

import sys
del sys.modules['project.my_app.models']
from project.my_app import models

def test_my_model():
  ...