【问题标题】:PyPa setup.py test scriptsPyPa setup.py 测试脚本
【发布时间】:2018-05-06 17:17:54
【问题描述】:

我正在尝试遵循python packaging docs 中的建议和结构。在 setup 函数中,您可以使用 tests_require 指定测试的依赖关系。您可以通过指定scripts 在安装时运行脚本。但是我可以有一个只在测试设置的情况下运行的脚本吗?


编辑:我的 setup.py 的重要部分
from setuptools import setup
# To use a consistent encoding
from codecs import open
from os import path
import subprocess
from setuptools import setup
from setuptools.command.test import test

class setupTestRequirements(test, object):
    def run_script(self):
        cmd = ['bash', 'bin/test_dnf_requirements.sh']
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        ret = p.communicate()
        print(ret[0])

    def run(self):
        self.run_script()
        super(setupTestRequirements, self).run()

...
setup(
    ...
    scripts=['bin/functional_dnf_requirements.sh'],
    install_requires=['jira', 'PyYAML'],
    tests_require=['flake8', 'autopep8', 'mock'],

    cmdclass={'test': setupTestRequirements}
)

【问题讨论】:

    标签: python python-2.7 pip python-packaging


    【解决方案1】:

    这并不意味着scripts 中的文件将在安装包时执行。关键字scripts 用于标记包中的python 文件,这些文件旨在在包安装后作为独立程序运行(可能名称有点误导)。示例:您有一个文件spam,其内容为:

    #!/usr/bin/env python
    
    if __name__ == '__main__':
        print('eggs!')
    

    如果您将此文件标记为脚本,将其添加到您的setup.py 中的scripts

    from setuptools import setup
    
    setup(
        ...
        scripts=['spam'],
    )
    

    安装包后,您可以在终端中将spam 作为独立程序运行:

    $ spam
    eggs!
    

    阅读this tutorial 了解有关命令行脚本的更多信息。


    现在,如果您想在测试中执行自定义代码,您必须覆盖默认的test 命令。在你的setup.py:

    from setuptools.command.test import test
    
    class MyCustomTest(test):
    
        def run(self):
            print('>>>> this is my custom test command <<<<')
            super().run()
    
    setup(
        ...
        cmdclass={'test': MyCustomTest}
    )
    

    现在您会在运行测试时注意到额外的打印:

    $ python setup.py test
    running test
    >>>> this is my custom test command <<<<
    running egg_info
    ...
    running build_ext
    
    ----------------------------------------------------------------------
    Ran 0 tests in 0.000s
    
    OK
    

    编辑:如果您想在执行测试之前运行自定义 bash 脚本,请调整 MyCustomTest.run() 方法。示例脚本script.sh:

    #!/usr/bin/env bash
    echo -n ">>> this is my custom bash script <<<"
    

    setup.py 中适配MyCustomTest 类:

    import subprocess
    from setuptools import setup
    from setuptools.command.test import test
    
    
    class MyCustomTest(test):
    
        def run_some_script(self):
            cmd = ['bash', 'script.sh']
            # python3.5 and above
            # ret = subprocess.run(cmd, stdout=subprocess.PIPE, universal_newlines=True)
            # print(ret.stdout)
    
            # old python2 versions
            p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            ret = p.communicate()
            print(ret[0])
    
        def run(self):
            self.run_some_script()
            super().run()
    

    输出:

    $ python setup.py test
    running test
    >>> this is my custom bash script <<<
    running egg_info
    writing spam.egg-info/PKG-INFO
    writing dependency_links to spam.egg-info/dependency_links.txt
    writing top-level names to spam.egg-info/top_level.txt
    reading manifest file 'spam.egg-info/SOURCES.txt'
    writing manifest file 'spam.egg-info/SOURCES.txt'
    running build_ext
    
    ----------------------------------------------------------------------
    Ran 0 tests in 0.000s
    
    OK
    

    【讨论】:

    • 感谢您的解释!我可以将命令类 dict 的值设为 bash 脚本而不是 python 函数吗?还是我应该只创建一个调用脚本的函数?
    • @LiamPieri 应该是一个覆盖正确命令类的类(自定义测试命令应该是从setuptools.command.test模块覆盖test类的类,自定义build命令应该是一个类从distutils.command.build 模块覆盖类build 等等)。尽管如此,没有人规定您的命令类 应该 做什么,因此您可以从那里调用任何 bash 脚本。我很快就会用一个例子来更新答案。
    • @LiamPieri 检查更新的答案,底部添加了运行 bash 脚本的示例,现在应该也可以使用 python2...
    • 谢谢!在实现这一点时,我遇到了一个奇怪的问题,但这对我来说没有意义。我使用的是 2.7,所以我的超级必须接受 args。所以我用super(MyTestClass, self) 调用super,但它向我抛出了这个错误super() argument 1 must be type, not classobj。这没有任何意义,所以我将它作为 super(type(MyTestClass, self) 输入,它吐回 self 不是该类型的实例。
    • @LiamPieri 有趣,不知道这个:related question on SO。将object 添加到您的交互链以修复错误:class setupTestRequirements(test, object): ... 我不做python2.7,因此不太了解它的规则。
    猜你喜欢
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多