Tox和lib以及lib64和site-packages

时间:2017-05-23 22:14:47

标签: python testing coverage.py tox

我使用toxcoverage.py在我的连续构建服务器中运行我的Python项目测试。我还有一个来自供应商(在PyPI上不可用)的软件包pkg_x,我使用python3.5 setup.py install安装了该软件包,并将其放在/usr/lib/python3.5/site-packages中。现在我需要将该包用于测试代码。

我当前的tox.ini看起来像这样:

[tox]
envlist = py35

[testenv]
deps = nose
       coverage
commands = coverage run -m nose []
sitepackages = True

我按照这样的方式运行测试:

python3.5 -m tox -- --verbose --with-doctest

失败的原因 - 我的本地setup.py中列出的依赖包(例如more_itertools等公共内容)都没有找到,即使它确实创建了似乎.tox/py35/lib/python3.5/site-packages/more_itertools的目录包含相关的包。如果我启动.tox/py35/bin/python3.5sys.path看起来像这样:

>>> [re.compile('.*\\.tox').sub('.tox', x) for x in sys.path]
['',
 '.tox/py35/lib64/python35.zip',
 '.tox/py35/lib64/python3.5', 
 '.tox/py35/lib64/python3.5/plat-linux',
 '.tox/py35/lib64/python3.5/lib-dynload',
 '/usr/lib64/python3.5',
 '/usr/lib/python3.5',
 '.tox/py35/lib/python3.5/site-packages']

如果我从sitepackages = True删除了tox.ini行,那么我确实会在more_itertools这样的包中以及我setup.py依赖项中的其他内容中走得更远现在可以找到,但我上面提到的供应商包pkg_x仍然无法找到。 sys.path看起来像这样:

>>> [re.compile('.*\\.tox').sub('.tox', x) for x in sys.path]
['',
 '.tox/py35/lib64/python35.zip',
 '.tox/py35/lib64/python3.5', 
 '.tox/py35/lib64/python3.5/plat-linux',
 '.tox/py35/lib64/python3.5/lib-dynload',
 '/usr/lib64/python3.5',
 '/usr/lib/python3.5',
 '.tox/py35/lib/python3.5/site-packages',
 '/usr/lib64/python3.5/site-packages',
 '/usr/lib/python3.5/site-packages']

在任何情况下.tox/py35/似乎都不包含供应商包pkg_x。虽然我手动启动/usr/lib/python3.5/site-packages时列出了目录.tox/py35/bin/python3.5,但在运行测试时实际上找不到pkg_x

看起来sitepackages = True与其记录的内容有相反的效果 http://tox.readthedocs.io/en/latest/config.html#confval-sitepackages=True|False,对吧?

建议非常感谢!

2 个答案:

答案 0 :(得分:5)

Tox创建一个virtualenv,然后从该环境中运行它的测试。

--sitepackages参数是一个开关,用于确定virtualenv是否可以访问全局安装的包。

运行tox的“正常”方式是简单地说tox;通过pip或OS软件包安装它应该把它放到你的路径中。即:

$ tox

与说法相同:

$ tox -c tox.ini

你直接调用tox的地方python -m tox,它可能会有所作为,但这对我来说是个红旗。此命令似乎不太可能激活相关的虚拟环境,这可以解释您的软件包可用性问题。它适合,因为当你省略sitepackages时,它实际上添加了全局包,因为它认为它在virtualenv中,因此添加了它认为的local站点包,尽管它们实际上是全局的。当你把它变成真的时会发生相反的情况,因为当它寻找全局包时它找不到它们。无论如何,因为你没有像预期的那样调用tox,它就像我们一样困惑。

所以只需使用提供的tox命令。

但是等等还有更多:你说你有一个必需的包,但在pypi上没有。那么tox如何安装呢? tox文档提出了两种方法(使用requirements.txt),但这里最直接的描述是激活env并手动安装。

如果您需要进一步调试也很好:进入.tox目录并手动激活venv。例如:

$ source .tox/testenv/bin/activate

(其中testenv是您在tox.ini中括号中使用的名称。

现在安装包,不过你在以前做过:pip install pkg_x

以这种方式完成后取消激活:

$ deactivate

现在试试tox

如果我们走在正确的轨道上learn more about virtualenv here

答案 1 :(得分:2)

我的问题的解决方案似乎是改变commands中的tox.ini行:

commands = coverage run -m nose []

到此:

commands = python -m coverage run -m nose []

效果是python现在是一个virtualenv-mapped命令,它加载正确的Python解释器,加载coverage模块并运行它。如果没有python -m,它只会找到我coverage中的PATH个可执行文件并运行它,结果不可预测。可以使用whitelist_externals,但它只会助长问题。

然后,如果我添加sitepackages = True行,它会成功看到我从供应商处安装的pkg_x,并且我的测试成功。