我非常简单的示例项目包含:
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()
我的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中运行它(在Ubuntu 18.04.1上为Python 3.6.6)可以使我:
$ 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']
-为什么?
答案 0 :(得分:2)
setuptools中的测试扫描程序将在子目录中的任何 *.py
文件中查找测试,__init__.py
除外。是的,其中包括__main__.py
,它将在其上调用__import__()
,从而使其主要套件得以执行。
如果您希望能够运行python -m addtest
并让其运行您的__main__.py
代码,则可能需要添加标准的“仅在这确实是主要保护时才运行”保护:
if __name__ == "__main__":
...
(然后,如果您执行python -m
,则代码将运行,但是如果文件由setup.py test
加载,则将不会运行)
答案 1 :(得分:1)
setuptools docs说明了默认情况下setuptools如何扫描单元测试。
因为正如您所说,没有编写或指定任何单元测试,所以setuptools
可以使用默认行为。
来自setuptools docs的一些参考资料对此进行了详细说明,并在下面指定了如何设置测试套件:
test_loader
如果您想使用 查找要运行的测试的方法与通常的安装工具不同 使用时,可以在此参数中指定模块名称和类名称。
...
模块名称和类名称必须用:分隔。此参数的默认值为"setuptools.command.test:ScanningLoader"
。如果要使用默认的单元测试行为,则可以将"unittest:TestLoader"
指定为test_loader
参数。 这将防止自动扫描子模块和子包。
...
test_suite
命名unittest.TestCase
子类(或包)的字符串 或包含其中一个或多个模块的模块,或此类模块的方法 子类),或者命名一个可以不带参数调用的函数 并返回unittest.TestSuite
。
如果命名套件是模块,则 该模块具有一个additional_tests()
函数,该函数被调用,并且 结果将添加到要运行的测试中。如果命名套件是 包,则将所有子模块和子包递归添加到 整体测试套件。指定此参数可启用
test
命令来运行 指定的测试套件,例如通过setup.py test
。请参阅 下面的test
命令以获取更多详细信息。
...
setup( # ... test_suite="my_package.tests.test_all" )
这与该线程上的another answer一起为您提供了至少两个选项,以确保python setup.py test
不运行控制台脚本:
setuptools
查找测试套件的方式。if __name__ == "__main__":
周围添加main()
您正在使用的单元测试库可能会提供另一个选项。例如,Pytest的integration guide for setuptools
用其自己的命令替换了test
命令。
关于系统参数
sys.argv
是['setup.py','test']
,因为您用参数python
调用了setup.py test
答案 2 :(得分:0)
我认为您必须在setup.py中指定测试的入口点。否则,它将传递给main.py。