Можно ли проверить, что тестовые зависимости не попали в реальный код с помощью python / pytest - PullRequest
5 голосов
/ 05 июня 2019

TL; DR: Если я использую pytest и некоторые другие зависимости только для тестирования, можно ли утверждать, что ни одна из этих зависимостей только для теста не просочилась в реальный, не тестовый код?

В Java, когда я запускаю тесты, сами тесты и тестируемый код будут выполняться в разных загрузчиках классов с их собственными зависимостями.Таким образом, если в тестируемом коде случайно упоминается testng, тесты не пройдут, даже если testng выполняет тесты.

Может ли то же самое быть достигнуто в Python?Если мой не тестовый код случайно импортирует pytest, могу ли я его перехватить и тесты пройдут неудачно?Я не понимаю, как этого добиться.

Хотя setuptools, pip и т. Д. Позволяют относительно легко разделять зависимости между установкой / запуском и разработкой / тестированием и даже избегать загрязнения текущего venv,они все еще присутствуют при выполнении тестов.Это означает, что выполнение python setup.py test для модуля может пройти, но python setup.py install, сопровождаемое чем-то настолько простым, как импорт модуля, может привести к сбою.

Дано: cat setup.py

from setuptools import setup, find_packages

setup(
    name="brettpy",
    version="0.0.1",
    packages=find_packages(),
    setup_requires=["pytest-runner",],
    tests_require=["pytest",],
)

cat setup.cfg

[aliases]
test=pytest

cat brettpy/__init__.py

import pytest

cat tests/test_brettpy.py

def test_import_brettpy():
    import brettpy
    del brettpy

def test_run_main():
    from brettpy import __main__ as main
    main.main()

... python setup.py test пройдет, но python setup.py install && python -m brettpy не удастсяwith:

ModuleNotFoundError: No module named 'pytest'

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

Ответы [ 2 ]

3 голосов
/ 07 июня 2019

Вы можете явно протестировать импорт test, используя Python modulefinder. Возможно, это не самое красивое из решений:

from modulefinder import ModuleFinder

def test_imports():
    finder = ModuleFinder()
    finder.run_script("PATH_TO_MAIN_SCRIPT")
    tests_require = ["pytest",]  # you can also get this list straight from `setup.py`
    overlapping = [mod for mod in finder.modules.keys() for req in tests_require if req in mod]
    assert not overlapping

Или, если вы не хотите использовать понимание списка:

    for mod_name in finder.modules.keys():
        for req in tests_require:
            assert req not in mod_name  # module could be pytest.something, _pytest, etc.
0 голосов
/ 07 июня 2019

Вы можете попробовать что-то вроде этого: https://stackoverflow.com/a/1592578/9095840

def no_test():
    try:
        pytest
    except NameError:
        pass
    else:
        exit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...