我使用tox
和coverage.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.5
,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']
如果我从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,对吧?
建议非常感谢!
答案 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
,并且我的测试成功。