多个python版本的tox覆盖范围

时间:2016-04-13 22:39:41

标签: python-3.x code-coverage tox

以下是项目和输出的link,您可以使用它来重现我在下面描述的问题。

我对 tox 使用覆盖率来对付多个版本的python。我的tox.ini文件看起来像这样:

[tox]
envlist =
    py27
    py34

[testenv]
deps =
    coverage

commands =
    coverage run --source=modules/ -m pytest
    coverage report -m

我的问题是覆盖只能使用一个版本的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

针对上述代码运行覆盖将错误地报告py27和py34的第6行(“print('3')”)是“Missing”。它应该只是缺少py34。

我知道为什么会发生这种情况:我的基础操作系统(使用python2.7)上安装了覆盖范围。因此,当运行 tox 时,它会注意到已经安装了coverage并从基本操作系统继承了覆盖范围,而不是将其安装在它创建的virtualenv中。

对于py27,这很好,但是在py34的覆盖率报告中会导致错误的结果。我有一个hacky,临时解决方案:我需要稍早版本的覆盖(相对于我的基本操作系统上安装的版本),以便tox将被迫在virtualenv中安装单独的覆盖副本。 E.g。

[testenv]
deps =
    coverage==4.0.2
    pytest==2.9.0
    py==1.4.30

我不喜欢这种解决方法,但它是我现在发现的最好的。有关强制tox在其virtualenv中安装当前版本的覆盖范围的方法的任何建议,即使我已经在我的基础操作系统上安装它了吗?

2 个答案:

答案 0 :(得分:5)

我今天遇到了这个问题,但找不到简单的答案。所以,为了将来的参考,这是我想出的解决方案。

  1. 创建一个envlist,其中包含将要测试的每个Python版本以及cov的自定义环境。
  2. 对于所有版本的Python,请设置COVERAGE_FILE环境变量以将.coverage文件存储在{envdir}中。
  3. 对于cov env,我使用两个命令。
      结合报告的
    1. coverage combine
    2. coverage html生成报告,如有必要,无法通过测试。
  4. 创建包含.coveragerc部分的[paths]文件,以列出source=个位置。
    1. 第一行是找到实际源代码的地方。
    2. 后续行是将通过`coverage combine'
    3. 消除的子路径
  5. <强> 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
    

    <强> .coveragerc:

    [paths]
    source=
        src/
        .tox/py*/lib/python*/site-packages/
    

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

    • tox不处理Shell扩展{toxworkdir}/py*/.coverage,因此我们需要调用shell(bash -c)来获得必要的扩展。
      • 如果有人倾向于你,你可以单独输入所有路径而不是跳过所有这些箍,但这会为每个.coverage env添加维护和pyNN文件依赖。
    • /usr/bin/env bash -c '...'以确保我们获得bash的正确版本。使用env的完整路径可以避免设置whitelist_externals
    • '{envpython} -m coverage ...'确保我们为python env。{/ li>调用正确的coveragecov
    • 注意:此解决方案的一个不幸问题是cov env依赖于py{27,36,35,34,33}的调用,这种调用有一些不太理想的副作用。
      • 我的建议是仅通过cov调用tox
      • 永远不要调用tox -ecov因为
        • 由于缺少.coverage文件或
        • ,它可能会失败
        • 它可以给出奇怪的结果(结合不同的测试)。
      • 如果必须将其作为子集(tox -epy27,py36,cov)调用,请先清除.tox目录(rm -rf .tox)以避免丢失.coverage文件问题。< / LI>

答案 1 :(得分:0)

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