Почему при запуске setup.py test запускается мой консольный скрипт? - PullRequest
0 голосов
/ 28 сентября 2018

Мой очень простой пример проекта содержит:

addtest/
  setup.py
  addtest/
    __init__.py
    __main__.py
    app.py

Мой app.py просто:

def main():
    raise SystemExit("Command line entry point called.")

Мой __main__.py просто:

from addtest.app import main
main()

My setup.py содержит:

from setuptools import setup, find_packages

setup(
    name='AddTest',
    version='1.0',
    packages=find_packages(),

    entry_points={
        'console_scripts': ['addtest = addtest.app:main']
    },
)

Я ожидаю, что выполнение python setup.py test ничего не даст, так как не написано ни одного модульного теста.Однако, запуск его в чистом virtualenv (Python 3.6.6 в Ubuntu 18.04.1) дает мне:

$ python setup.py test
running test
running egg_info
writing AddTest.egg-info/PKG-INFO
writing dependency_links to AddTest.egg-info/dependency_links.txt
writing entry points to AddTest.egg-info/entry_points.txt
writing top-level names to AddTest.egg-info/top_level.txt
reading manifest file 'AddTest.egg-info/SOURCES.txt'
writing manifest file 'AddTest.egg-info/SOURCES.txt'
running build_ext
Command line entry point called.

Обратите внимание на Command line entry point called., что означает, что он вызывает консольный скрипт, сгенерированный из моего __main__.py(или, может быть, просто вызываете python -m addtest).

Почему setup.py вызывает консольный скрипт, когда я хочу, чтобы он запускал тесты?Дальнейшая проверка выполнения сценария показывает, что sys.argv равно ['setup.py','test'] - почему?

Ответы [ 3 ]

0 голосов
/ 28 сентября 2018

Тестовый сканер в setuptools будет искать тесты в любом *.py файле, найденном в ваших подкаталогах, кроме __init__.py.Да, это включает в себя __main__.py, он вызовет __import__() для него, что приведет к выполнению его основного набора.

Если вы хотите иметь возможность запустить python -m addtest и запустить его __main__.pyкод, вы можете добавить стандартную защиту «только при запуске», если это действительно основная защита:

if __name__ == "__main__":
   ...

(тогда, если вы выполните python -m, код будет работать, но он не будет работать, еслифайл загружается setup.py test)

0 голосов
/ 28 сентября 2018

Документы setuptools объясняют, как setuptools сканирует модульные тесты по умолчанию.

Поскольку, как вы говорите, ни один модульный тест не написан или не указан, setuptools может использовать поведение по умолчанию.

Ниже приведены пара ссылок из setuptools docs , в которых подробно описывается это, а также указывается, как настроить наборы тестов:

  1. test_loader Если вы хотите использовать другой способ поиска тестов, отличающийся от того, который обычно использует setuptools, вы можете указать имя модуля и имя класса в этом аргументе.
    ...
    Имя модуля и имя класса должны быть разделены символом:.Значением по умолчанию этого аргумента является "setuptools.command.test:ScanningLoader".Если вы хотите использовать стандартное поведение юнит-теста, вы можете вместо этого указать "unittest:TestLoader" в качестве аргумента test_loader. Это предотвратит автоматическое сканирование субмодулей и подпакетов.

  2. ... test_suite Строка с именемunittest.TestCase подкласс (или пакет или модуль, содержащий один или несколько из них, или метод такого подкласса), или именование функции, которая может быть вызвана без аргументов и возвращает unittest.TestSuite.

    Если названный набор является модулем, а модуль имеет функцию additional_tests(), он вызывается и результаты добавляются в выполняемые тесты.Если названный набор является пакетом, любые субмодули и подпакеты рекурсивно добавляются в общий набор тестов.

    Указание этого аргумента позволяет использовать команду test для запуска указанного набора тестовНапример, через setup.py test.См. Раздел о команде test ниже для получения более подробной информации.
    ...

         setup(
         # ...
         test_suite="my_package.tests.test_all"
     )

В сочетании с другим ответом в этой теме у вас останется как минимум параиз опций, чтобы гарантировать, что python setup.py test не запускает консольный сценарий:

  1. Настройте, как setuptools ищет наборы тестов.
  2. Добавить if __name__ == "__main__": вокруг main()

Еще одна опция может быть предоставлена ​​библиотекой модульного тестирования, которую вы используете.Например, Pytest имеет руководство по интеграции для setuptools, которое заменяет команду test на собственную.


Относительно sysargs

sys.argv равно ['setup.py','test'], потому что вы вызвали python с аргументами setup.py test

0 голосов
/ 28 сентября 2018

Я думаю, что вы должны указать точку входа для теста в вашем файле setup.py.В противном случае он передает его в main.py.

...