毒性 0% 覆盖率

Tox 0% coverage

我有一个 python 项目,我在其中使用:

还有更多。

基本上,我想将 tox 添加到我的 gitlab 管道中。几乎一切似乎都有效,从 tox 调用 mypyflake8black 工作正常。但是当我在启用覆盖的情况下调用 tox -e py37(所以我想 运行 测试)时,测试是 运行,我可以看到它们的结果,但覆盖是 0%100% 仅适用于空 __init__ 文件等)并且我收到警告:Coverage.py warning: No data was collected. (no-data-collected).

这是我的 pytest 相关部分 tox.ini:

[tox]
envlist = flake8,mypy,black,py37

[testenv]
extras = tests
commands=
    pytest --cov -ra --tb=short {posargs}

这是我的 .coveragerc:

[run]
branch = True
source =
    foo

omit = 
    foo/__init__.py
    foo/__main__.py
    foo/bar/__init__.py
    foo/baz/__init__.py

[report]
exclude_lines =
    pragma: no cover
    if __name__ == .__main__.
show_missing = True

我有一个可用的 setup.py,其中包括所有需要的包:pytestpytest-cov 以及更多样式等(有效)。我的 tests 文件夹中也有 __init__.py

有趣的是,如果我从命令行(在 pipenv 中)调用与在 tox.ini 中相同的命令:pytest --cov -ra --tb=short,我会得到相同的结果,但结果正常覆盖范围(在我的例子中是 100%)。

有办法解决吗?我不希望我的管道显示错误的覆盖范围 + 即使它们以某种方式神奇地得到正确的覆盖范围,我仍然希望在本地看到它。

P.S 当我试图解决这个问题时,我用 tox --sitepackages -e py37 调用了 tox,但出现了一些错误,例如 test command found but not in testenv。除了这些错误之外,我当时的报道还不错。但是后来我从我的全局 pip 寄存器中卸载了 toxpytestpytest-cov,现在有或没有 --sitepackages 标志我仍然得到 0% 覆盖率

根本原因pytest在runnung tox期间使用安装的源(在site-packages下),而报道记者计算点击率工作目录中的文件(即您的本地 git 存储库)。


解决方案

将 tox 的虚拟环境路径添加到覆盖范围:

[testenv]
pytest --cov={envsitepackagesdir}/foo

有关详细信息,请阅读 substitutions for virtualenv-related sections


解决方法

PYTHONPATH 设置为工作目录(即 export PYTHONPATH=.)。请注意,您需要通过以下方式将 PYTHONPATH 传递给 tox

[testenv]
passenv =
    PYTHONPATH

这很简单,但是使用这种方式,您不会测试安装,因为测试是在工作目录中的文件上运行的。

基于@betontalpfa 的回答,我认为另一种可能的解决方案(在我的用例中似乎效果很好)是修改 tox.ini 以包括:

[testenv]
deps = -e .
...

AFAIK,通过使用 pip 的可编辑模式将包安装在工作目录中,您既可以测试已安装的包,又可以避免文件路径不匹配导致覆盖率为 0%。

简单的解决方案

在tox.ini中有usedevelop=True

[testenv]
usedevelop=True
pytest --cov=foo

这导致与@zvi-baratz 的解决方案相同的行为,但不那么骇人听闻。

警告

这里唯一需要注意的是,如果包中有自定义 install_command,则无法使用此解决方案。请参阅 docs 了解更多信息。

如果是这样,您可以使用 --cov={envsitepackagesdir}/foo 作为 解决方法.

为什么不一直使用 envsitepackagesdir

因为它导致覆盖率报告具有更长的路径,这些路径指向由 tox 创建的 python 环境中的文件,而不是实际的项目路径。