39

我制作了我的项目,setuptools我想用tox. 我在变量中列出了依赖项并添加到setup()参数 ( tests_requireand extras_require)。我的项目需要安装列出的所有依赖项以tests_require进行测试,但pip install没有安装它们。

我试过了,但没有奏效:

install_command = pip install {opts} {packages}[tests]

如何安装测试依赖项而无需管理多个依赖项列表(即在变量test_requirements.txttests_require变量中列出所有依赖项)?

4

4 回答 4

57

我通过稍微滥用额外要求来实现这一点。您几乎在那里尝试了 extras 语法,只是tests_requiredeps 不会以这种方式自动可用。

setup.py这样:

from setuptools import setup

test_deps = [
    'coverage',
    'pytest',
]
extras = {
    'test': test_deps,
}

setup(
    # Other metadata...
    tests_require=test_deps,
    extras_require=extras,
)

然后,您可以使用 extras 语法安装测试依赖项,例如从项目根目录:

$ pip install .[test]

为 Tox in 提供相同的语法tox.ini,无需调整默认值install_command

[testenv]
commands = {posargs:pytest}
deps = .[test]

现在您不需要在两个地方维护依赖关系列表,它们在发布包的位置表示:在包元数据而不是requirements.txt文件中。

似乎这种小额外的黑客行为并不少见

于 2016-12-30T15:44:02.670 回答
16

解决方案

Tox 2.6 引入了extras选项。这将从extras它刚刚构建的 sdist 安装,仅适用于该 sdist 并且当时它正在执行正常的 sdist 安装。

setup.py 应如下所示:

setuptools.setup(
    ...
    extras_require={
        'tests': ['pytest>=3.7.0', 'more_packages'],
    },
    ...
 )

tox.ini 应该如下所示:

[testenv]
...
extras = tests
...

关注点

其他方法可能会得到类似的结果,但会引入不必要的风险并限制其他功能的有用性:

deps =.[tests]有点小题大做。该字段用于环境需要的包。如果 setup.py install_requires 引用了您开发的另一个包,您可以使用它来拉入它的预发布版本。如图所示,它将从您的工作目录(无论处于何种状态!)安装您的整个包,只是为了获取tests. install_command接下来将运行,安装新创建的 sdist。简而言之,sdist 的问题可能会被掩盖,因为您已经从工作副本安装。

编辑install_command是多余的。它会覆盖通过deps. (同样,也许你用它来安装一个特定版本的包)。

tests_require运行时使用python setup.py testTox建议避免python setup.py test,这样您就可以忽略tests_require所有内容。

于 2019-06-14T02:03:23.413 回答
4

您可以做的是拥有一个文件(称为test_requirements.txt)并列出测试依赖项,如下所示:

dnspython==1.12.0
easydev==0.8.3
enum34==1.0.4
fabric==1.10.1
...

然后,在 中setup.py,解析文件内容并将其存储在列表中,并将该列表传递给setup

tests_require = [line.strip() for line in 
                 open('test_requirements.txt')
                 if line.strip() and not line.strip().startswith('--')]

setuptools.setup(
    ...
    tests_require=tests_require,
    ...
)
于 2015-04-25T22:24:44.837 回答
2

如果您使用以下命令,Tox 将test_requires在运行测试之前安装您的:

commands = {envpython} setup.py test

您还需要添加到 setup.py中的测试在哪里:

test_suite="tests_module"

最后,这里有一个类似问题的答案,有一个很好的例子。

于 2018-07-23T18:52:19.193 回答