毒性 0% 覆盖率

dab*_*ues 9 python coverage.py pytest python-3.x tox

我有一个我使用的python项目:

  • 管道
  • 毒物
  • pytest

还有很多。

基本上,我想添加tox到我的 gitlab 管道中。而几乎一切似乎工作,打电话mypyflake8black从TOX工作正常。但是,当我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}
Run Code Online (Sandbox Code Playgroud)

这是我的.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
Run Code Online (Sandbox Code Playgroud)

我有一个工作setup.py,其中包括所有需要的包:pytestpytest-cov还有更多的风格等(有效)。__init__.py我的tests文件夹里也有。

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

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

PS 当我试图解决这个问题时,我调用了 tox withtox --sitepackages -e py37并且出现了一些错误,例如test command found but not in testenv. 除了这些错误之外,我当时的报道还不错。但后来我卸载toxpytestpytest-cov从我的全球PIP寄存器和现在有或无--sitepackages标志我仍然可以0%覆盖

bet*_*pfa 12

根本原因pytest在 runnung 期间tox使用已安装的源(在 site-packages 下),而覆盖报告者计算工作目录(即您的本地 git repo)中的命中文件。


解决方案

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

[testenv]
pytest --cov={envsitepackagesdir}/foo
Run Code Online (Sandbox Code Playgroud)

有关virtualenv 相关部分的更多详细阅读替换


变通方法

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

[testenv]
passenv =
    PYTHONPATH
Run Code Online (Sandbox Code Playgroud)

这很容易,但使用这种方式,您无需测试安装,因为测试是针对工作目录中的文件运行的。

  • 使用 `python -m pytest` 似乎也可以工作,出于类似的原因 - python -m 将 `.` 添加到 PATH (3认同)

jxc*_*r0w 7

简单的解决方案

usedevelop=True在tox.ini中有:

[testenv]
usedevelop=True
pytest --cov=foo
Run Code Online (Sandbox Code Playgroud)

这会导致与 @zvi-baratz 的解决方案相同的行为,但不那么 hacky。

警告

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

如果是这种情况,您可以--cov={envsitepackagesdir}/foo使用 .

为什么不envsitepackagesdir一直使用呢?

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