тесты tox/pytest проходят/не проходят в зависимости от того, установлен ли другой модуль в хост-среде

У меня есть ряд тестов pytest, развернутых с использованием tox, которые устанавливают старую версию модуля, затем импортируют ее, а затем устанавливают более новую версию того же модуля. Тесты проверяют, что обновление уже загруженного модуля вызывает предупреждение (чтобы сообщить пользователю о перезапуске сеанса/интерпретатора).

Моя проблема в том, что успех тестов зависит от того, установлена ​​ли старая версия модуля в хост-среде (например, pip install --user random_module && tox или pip uninstall random_module && tox). Я был очень удивлен, обнаружив, что тесты чувствительны к тому, что я установил в своем пользователе. Что происходит и как избежать этого взаимодействия, чтобы тесты выполнялись одинаково, независимо от того, что установлено в site-packages моего пользователя?

Подробнее о проекте

Я пишу пакет-оболочку для pip, позволяющий устанавливать пакеты из REPL/консоли/скрипта. Одно из осложнений, которое возникает при этом, заключается в том, что кто-то мог уже загрузить модуль, а затем установить обновление, но старая версия останется в памяти. В этих случаях мне нужно предупредить пользователя, что ему необходимо перезапустить сеанс, чтобы новая установка вступила в силу.


person reynoldsnlp    schedule 07.08.2019    source источник
comment
Я клонировал основную ветку, запускал pip install "pytest<5" && tox -e py37, затем pip install "pytest>=5" && tox -e py37, но результаты тестов были идентичными. Как я могу воспроизвести проблему?   -  person hoefling    schedule 07.08.2019
comment
@hoefling В ветке #3-origin выполните git pull, затем tox должно пройти все, кроме одного, но python3 -m pip install --user progress==1.4 && tox должно завершиться ошибкой на 3. Тесты зависят от пакета progress, который на данный момент является своего рода хаком. В конце концов, я положу пакеты с игрушками в свою тестовую папку, чтобы поиграть с ними.   -  person reynoldsnlp    schedule 07.08.2019
comment
Я понимаю, что вы имеете в виду, я действительно могу это воспроизвести, однако я не думаю, что это имеет какое-то отношение к текущей среде, поскольку tox запускает тесты в собственной изолированной среде. Я думаю, что это как-то связано с тем, что тесты не очищают установку progress - попробуйте запустить, например. .tox/py36/bin/pytest tests/functional/test_install.py::test_progress_already_loaded_warning результат теста будет чередоваться между отказом и прохождением, в зависимости от того, что осталось установленным после предыдущего выполнения.   -  person hoefling    schedule 07.08.2019
comment
Например. запустите .tox/py36/bin/pytest tests/functional/test_install.py::test_progress_already_loaded_warning; .tox/py36/bin/pip show progress | grep Version, чтобы увидеть, что я имею в виду.   -  person hoefling    schedule 07.08.2019
comment
Конечно! Я предполагал, что виртуальная среда каждый раз повторно инициализируется, но на самом деле она сохраняется. Я вижу в документы, что вы можете использовать флаг --recreate, чтобы заставить его работать заново. Спасибо за помощь, @hoefling! Если вы хотите превратить ваши комментарии в ответ, я с радостью приму его.   -  person reynoldsnlp    schedule 08.08.2019


Ответы (1)


Проблема с двумя тестами, переключающимися между сбоем и прохождением, заключается в том, что установка пакета progress не откатывается между запусками теста. Одним из возможных решений может быть принудительное воссоздание виртуальной среды с помощью tox с помощью запуска tox --recreate, как вы предложили в комментариях. Другим может быть реализация отката в приспособлении, например.

@pytest.fixture
def rollback_progress_package():
    yield  # wait for the test to finish
    subprocess.run(['pip', 'install', '--force-reinstall', 'progress==1.5'])

@pytest.mark.usefixtures('rollback_progress_package')
def test_progress_already_loaded_warning():
    ...

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

person hoefling    schedule 08.08.2019