一般提示和技巧

交互传递位置参数

如果您调用 tox 这样地:

tox -- -x tests/test_something.py

之后的参数 -- 将在您指定的所有位置替换 {{posargs}} 在测试命令中,例如使用 pytest

[testenv]
# Could also be in a specific ``[testenv:<NAME>]`` section
commands = pytest {posargs}

或使用 nosetests

[testenv]
commands = nosetests {posargs}

以上内容 tox 调用将触发测试运行器在第一次失败后停止,并仅运行特定的测试文件。

您可以使用以下语法指定位置参数的默认值:

[testenv]
commands = nosetests {posargs:--with-coverage}

依赖项更改和跟踪

创建虚拟环境和安装依赖项是一项昂贵的操作。因此,只要有可能,tox就会尽量避免它,这意味着除非它绝对确定地检测到需要执行更新,否则它永远不会执行此操作。tox 环境创建由以下部分组成:

  • 创建虚拟环境

  • 安装在DEPS内部指定的依赖项

  • 如果是库项目(具有构建包阶段),则安装库依赖项(具有潜在的附加组件)

这三个步骤只执行一次(假设它们都成功了)。没有检测到该步骤的特征更改的后续调用将不会以任何方式改变虚拟环境。当检测到任何步骤的更改时,整个虚拟环境将被删除,操作从头开始(这是因为很难确定需要哪些增量更改-例如,依赖项可能会从一个依赖项迁移到另一个依赖项,在这种情况下,我们需要在删除旧依赖项的同时安装新依赖项)。

以下是我们目前跟踪的每一步的特征:

  • 虚拟环境特性被绑定到python路径 basepython 也会解析(如果此配置更改,将重新创建虚拟环境),

  • deps 部分更改(表示条目的任何字符串级更改,注意要求文件内容更改不会被跟踪),

  • 可在以下位置跟踪库依赖项 extras 级别(因为没有Python API可以以非特定于工具的方式查询实际的依赖关系,例如setuptools有一种方式,flit有另一种方式,而POLITE有另一种方式)。

每当您更改未跟踪的特征时,我们建议您手动触发 tox 环境的重建,方法是将 -r tox 调用的标志。例如,对于setuptools项目,只要您修改 install_requires 关键字在下一次运行时通过传递rereate cli tox标志强制重新创建tox环境。

选择要对其运行测试的一个或多个环境

使用 -e ENV[,ENV36,...] 选项,显式列出要在其上运行测试的环境。例如,给定前面的狮身人面像示例,您可以调用:

tox -e docs

这将使 tox 仅管理 docs 并调用其测试命令。您可以指定多个这样的环境:

tox -e py27,py36

它将运行 py27py36 测试环境。特殊的价值 ALL 选择所有环境。

您还可以在中指定环境列表 tox.ini

[tox]
envlist = py27,py36

或者从命令行或环境变量覆盖它 TOXENV

export TOXENV=py27,py36 # in bash style shells

在多个tox运行之间访问包工件

如果您有多个使用tox的项目,则可以使用 distshare 目录在哪里 tox 将复制sdist包,以便另一次tox运行可以找到“最新的”依赖项。此功能允许您在自己的计算机上针对未发布的开发版本甚至未提交的版本测试包。

默认情况下, {{homedir}}/.tox/distshare 将用于复制入和复制出工件(即Python包)。

对于项目 two 依赖于 one Package您可以使用以下条目:

# example two/tox.ini
[testenv]
# install latest package from "one" project
deps = {distshare}/one-*.zip

就这样。项目上运行的tox one 将sdist-package复制到 distshare 目录,在该目录之后, tox 在项目上运行 two 会抓住它,因为 deps 包含一个条目,该条目带有 one-*.zip 图案。如果有多个匹配的软件包,将采用最高版本。 tox 使用 verlib 要比较必须符合的版本字符串,请执行以下操作 PEP 386 .

如果您要将此功能与 Jenkins, 另外,还可以查看 在Jenkins作业之间访问包工件 .

basepython默认值,覆盖

对于任何 pyXY 测试环境名称基础 pythonX.Y 将在您的系统中搜索可执行文件 PATH 。同样,对于 jythonpypy 各自的 jythonpypy-c 我们会找出他们的名字。必须存在可执行文件才能成功创建 virtualenv 环境。在Windows a上 pythonX.Y 将在典型的默认位置使用 C:\PythonXY\python.exe 模式。

所有其他目标都将使用该系统 python 取而代之的是。属性可以覆盖任何默认设置。 basepython 变量,例如:

[testenv:docs]
basepython = python2.7

避免昂贵的sdist

有些项目很大,运行一个sdist,然后每次都要安装,成本可能高得令人望而却步。要解决此问题,可以将两个不同的选项添加到 tox 部分。首先,你可以简单地要求 tox 测试,请不要做sdist:

[tox]
skipsdist=True

如果您这样做,您的本地软件包将不会安装到Virtualenv中。您可能对此没有意见,或者在您的命令部分采取措施来处理它:

[testenv]
commands = python setup.py develop
           pytest

运行 setup.py develop 是一种足够常见的模式,它有自己的选择:

[testenv]
usedevelop=True

和相应的命令行选项 --develop, which will set skipsdist to True and then perform the setup.py develop step at the place where tox normally performs the installation of the sdist. Specifically, it actually runs pip install -e . 在幕后,它本身称为 setup.py develop .

中编码了一个优化,在以下情况下不会费心重新运行该命令 $projectname.egg-info 更新比 setup.pysetup.cfg .

理解 InvocationError 退出代码

当命令(由定义) commands = 在里面 tox.ini )失败,它有一个非零的退出代码,并且 InvocationError 异常由引发 tox

ERROR: InvocationError for command
       '<command defined in tox.ini>' (exited with code 1)

如果命令以 pytestpython setup.py test 例如,那么 pytest exit codes 都是相关的。

在Unix系统上,有一些 common exit codes 。这就是为什么对于大于128的退出代码,如果数字等于 <exit code> - 128 发现在 signal 模块,则会给出额外的提示:

ERROR: InvocationError for command
       '<command>' (exited with code 139)
Note: this might indicate a fatal error signal (139 - 128 = 11: SIGSEGV)

在哪里? <command> 中定义的命令 tox.ini ,去掉引号。

信号编号(例如,分段故障的信号编号为11)可在的“标准信号”部分找到。 signal man page 。它们的含义在 POSIX signals .

请注意,程序可能会发出具有任何值的自定义退出代码,因此应该参考它们的文档。

有时,根本不给出退出代码。有关示例,请参阅 pytest-qt issue #170 ,这里是Qt呼叫的地方 abort() 而不是 exit() .