Tox涵盖多个python版本

use*_*632 4 code-coverage python-3.x tox

这是项目和输出的链接,可用于重现我在下面描述的问题。

我使用的覆盖面TOX对蟒蛇的多个版本。我的tox.ini文件看起来像这样:

[tox]
envlist =
    py27
    py34

[testenv]
deps =
    coverage

commands =
    coverage run --source=modules/ -m pytest
    coverage report -m
Run Code Online (Sandbox Code Playgroud)

我的问题是,覆盖范围只能使用一个版本的python(在我的情况下为py27)运行,而不能同时使用py27和py34。每当我有依赖于python版本的代码执行时,这就是一个问题,例如:

def add(a, b):
    import sys
    if sys.version.startswith('2.7'):
        print('2.7')
    if sys.version.startswith('3'):
        print('3')
    return a + b
Run Code Online (Sandbox Code Playgroud)

针对上述代码运行覆盖率将错误地报告py27和py34的第6行(“ print('3')”)为“缺少”。对于py34,应该只缺少此字符。

我知道为什么会这样:覆盖已安装在我的基本操作系统(使用python2.7)上。因此,在运行Tox时,它会注意到Coverage已安装,并且从基本OS继承了Coverage,而不是将其安装在它创建的virtualenv中。

对于py27,这很好而且很花哨,但在py34的覆盖率报告中导致错误的结果。我有一个临时的变通办法:我需要一个较早版本的coverage(相对于基本OS上安装的版本),以便Tox将被迫在virtualenv中安装一份单独的coverage副本。例如

[testenv]
deps =
    coverage==4.0.2
    pytest==2.9.0
    py==1.4.30
Run Code Online (Sandbox Code Playgroud)

我不喜欢这种解决方法,但这是我目前发现的最好方法。关于强制tox在virtualenv中安装当前版本的Coverage的任何建议,即使我已经在基本OS上安装它了吗?

san*_*ore 6

我今天遇到了这个问题,但找不到简单的答案。因此,以下是我提出的解决方案,以供将来参考。

  1. 创建一个envlist,其中包含将要测试的每个Python版本以及的自定义环境cov
  2. 对于所有版本的Python,请将COVERAGE_FILE环境设置为varible以将.coverage文件存储在中{envdir}
  3. 对于covenv,我使用两个命令。
    1. coverage combine 合并了报告,并且
    2. coverage html 生成报告,并在必要时使测试失败。
  4. 创建一个.coveragerc文件,其中包含一个[paths]列出source=位置的部分。
    1. 第一行是找到实际源代码的位置。
    2. 后面的行是将由“ coverage Combine”消除的子路径。

tox.ini:

[tox]
envlist=py27,py36,py35,py34,py33,cov

[testenv]
deps=
    pytest
    pytest-cov
    pytest-xdist
setenv=
    py{27,36,35,34,33}: COVERAGE_FILE={envdir}/.coverage
commands=
    py{27,36,35,34,33}: python -m pytest --cov=my_project  --cov-report=term-missing --no-cov-on-fail
    cov: /usr/bin/env bash -c '{envpython} -m coverage combine {toxworkdir}/py*/.coverage'
    cov: coverage html --fail-under=85
Run Code Online (Sandbox Code Playgroud)

.coveragerc:

[paths]
source=
    src/
    .tox/py*/lib/python*/site-packages/
Run Code Online (Sandbox Code Playgroud)

配置中最特殊的部分是的调用coverage combine。这是命令的细分:

  • tox不处理Shell扩展{toxworkdir}/py*/.coverage,因此我们需要调用shell(bash -c)以获取必要的扩展。
    • 如果愿意的话,您可以单独输入所有路径,而不必跳过所有这些步骤,但这将为.coverage每个环境增加维护和文件依赖性pyNN
  • /usr/bin/env bash -c '...'以确保我们获得的正确版本bash。使用fullpath env避免进行设置whitelist_externals
  • '{envpython} -m coverage ...'确保我们调用正确的python,并coveragecovENV。
  • 注意:此解决方案的不幸问题是covenv依赖于其调用,py{27,36,35,34,33}而该调用具有一些不太理想的副作用。
    • 我的建议是仅cov通过调用tox
    • 永远不要调用,tox -ecov因为
      • 可能由于.coverage文件丢失而失败,或者
      • 它可能给出奇怪的结果(结合不同的测试)。
    • 如果必须将其作为子集(tox -epy27,py36,cov)调用,请先擦除.tox目录(rm -rf .tox),以避免丢失.coverage文件的问题。


Ned*_*der 1

我不明白为什么 tox 不能在每个 virtualenv 中正确安装覆盖范围。您应该获得两份不同的覆盖率报告,一份针对 py27,一份针对 py35。更好的选择可能是生成一份合并报告。用于coverage run -p记录每次运行的单独数据,然后coverage combine在报告前将它们合并。