【问题标题】:How can I combine coverage results with tox?如何将覆盖结果与毒性结合起来?
【发布时间】:2018-06-17 09:55:34
【问题描述】:

对于我的 mpu 包,我有执行环境依赖代码,例如

if sys.version_info < (3, 0):
   pass  # do something
else:
   pass  # do something else

还有一个 tox 文件

[tox]
envlist = py27,py36

[testenv]
deps =
    pytest
    pytest-cov
    pytest-pep8
    pydocstyle
commands =
    pip install -r test-requirements.txt
    pip install -e .[all]
    pytest .
    pydocstyle

还有一个 setup.cfg

[metadata]
description-file = README.md

[tool:pytest]
addopts = ./tests/ --doctest-modules --cov=./mpu --cov-report html:tests/reports/coverage-html --cov-report xml:tests/reports/coverage.xml --pep8 --ignore=docs/
doctest_encoding = utf-8

[pydocstyle]
ignore = D104, D105, D107, D301, D413, D203, D212, D100
match_dir = mpu

tox 文件似乎可以满足我的要求,但覆盖范围仅适用于其中一种经过测试的环境。我在branch coverage-combinedcoverage-combined 中看到过Reporting cumulative coverage across multiple Python versions,但它不起作用。对于第一次运行,它似乎没有执行所有测试,因为测试覆盖率比以前低得多。我的猜测是没有执行文档测试。对于第二次运行,我得到了

ERROR: InvocationError: '/home/moose/GitHub/mpu/.tox/py27/bin/coverage run --source=mpu/ setup.py test'

系统

$ coverage --version
Coverage.py, version 4.5.1 with C extension
Documentation at https://coverage.readthedocs.io

错误

现在我收到此错误:

======================================================================
ERROR: test_pd (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_pd
Traceback (most recent call last):
  File "/usr/lib/python3.6/unittest/loader.py", line 428, in _find_test_path
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.6/unittest/loader.py", line 369, in _get_module_from_name
    __import__(name)
  File "/home/moose/GitHub/mpu/tests/test_pd.py", line 8, in <module>
    from mpu.pd import example_df
  File "/home/moose/GitHub/mpu/mpu/pd.py", line 10, in <module>
    import pandas as pd
  File "/home/moose/.local/lib/python3.6/site-packages/pandas/__init__.py", line 42, in <module>
    from pandas.core.api import *
  File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/api.py", line 10, in <module>
    from pandas.core.groupby.groupby import Grouper
  File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/groupby/__init__.py", line 2, in <module>
    from pandas.core.groupby.groupby import (
  File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/groupby/groupby.py", line 49, in <module>
    from pandas.core.frame import DataFrame
  File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/frame.py", line 74, in <module>
    from pandas.core.series import Series
  File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/series.py", line 80, in <module>
    import pandas.plotting._core as gfx
  File "/home/moose/.local/lib/python3.6/site-packages/pandas/plotting/__init__.py", line 11, in <module>
    from pandas.plotting._core import boxplot
  File "/home/moose/.local/lib/python3.6/site-packages/pandas/plotting/_core.py", line 45, in <module>
    from pandas.plotting import _converter
  File "/home/moose/.local/lib/python3.6/site-packages/pandas/plotting/_converter.py", line 8, in <module>
    import matplotlib.units as units
  File "/home/moose/.local/lib/python3.6/site-packages/matplotlib/__init__.py", line 131, in <module>
    from matplotlib.rcsetup import defaultParams, validate_backend, cycler
  File "/home/moose/.local/lib/python3.6/site-packages/matplotlib/rcsetup.py", line 29, in <module>
    from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
  File "/home/moose/.local/lib/python3.6/site-packages/matplotlib/fontconfig_pattern.py", line 22, in <module>
    from pyparsing import (Literal, ZeroOrMore, Optional, Regex, StringEnd,
  File "/home/moose/.local/lib/python3.6/site-packages/pyparsing.py", line 943, in <module>
    collections.MutableMapping.register(ParseResults)
  File "/usr/lib/python3.6/abc.py", line 158, in register
    if issubclass(subclass, cls):
  File "/usr/lib/python3.6/abc.py", line 228, in __subclasscheck__
    if issubclass(subclass, scls):
  File "/usr/lib/python3.6/abc.py", line 228, in __subclasscheck__
    if issubclass(subclass, scls):
  File "/usr/lib/python3.6/typing.py", line 1154, in __subclasscheck__
    return super().__subclasscheck__(cls)
  File "/usr/lib/python3.6/abc.py", line 209, in __subclasscheck__
    ok = cls.__subclasshook__(subclass)
  File "/usr/lib/python3.6/typing.py", line 884, in __extrahook__
    if issubclass(subclass, scls):
  File "/usr/lib/python3.6/typing.py", line 1154, in __subclasscheck__
    return super().__subclasscheck__(cls)
  File "/usr/lib/python3.6/abc.py", line 209, in __subclasscheck__
    ok = cls.__subclasshook__(subclass)
  File "/usr/lib/python3.6/typing.py", line 884, in __extrahook__
[...]
  File "/usr/lib/python3.6/typing.py", line 884, in __extrahook__
    if issubclass(subclass, scls):
  File "/usr/lib/python3.6/abc.py", line 206, in __subclasscheck__
    elif subclass in cls._abc_negative_cache:
  File "/usr/lib/python3.6/_weakrefset.py", line 75, in __contains__
    return wr in self.data
RecursionError: maximum recursion depth exceeded in comparison

【问题讨论】:

  • 解决了吗?从最后的部分不清楚。你能澄清一下吗?
  • 不,没有解决。我只是发现 --parallel-mode 必须在 setup.py 之前并想注意它,这让我感到困惑。也许我应该从问题中删除这部分。
  • 看看这个 repo 有没有帮助? github.com/avara1986/gozokia
  • 啊,好吧,那是另一种方式。但我希望我能用tox做到这一点。我宁愿使用tox 作为执行与测试相关的所有内容的命令
  • 我认为begin,py{...},end 的模式适用于此,但我不明白为什么/如何导致ERROR: InvocationError

标签: python code-coverage coverage.py tox


【解决方案1】:

我假设您安装了pytest-cov。在这种情况下,附加覆盖范围相当简单。您只需将--cov-append 添加到[tool:pytest].addopts 部分即可。

[tool:pytest]
addopts = tests/ --doctest-modules --cov=./mpu --cov-append --cov-report html:tests/reports/coverage-html --cov-report xml:tests/reports/coverage.xml --pep8 --ignore=docs/
doctest_encoding = utf-8

这会将来自多个测试运行的覆盖率组合在一起。如果您拆分集成/单元测试,这也很有帮助。

【讨论】:

  • 虽然我很欣赏您的回答 (+1),但似乎无法解决问题。请参阅我添加到问题中的错误。
  • @MartinThoma 您发布的错误与--cov-append 选项无关-出于某种原因,测试使用unittest 而不是pytest 运行。你一定是改变了其他东西才导致这种情况。
  • 请补充您是如何发现unittest 是问题所在。我现在可以修复它:我直接调用coverage 而不是使用pytest 并让pytest-cov 调用覆盖范围。谢谢!
猜你喜欢
  • 1970-01-01
  • 2010-11-13
  • 2021-01-02
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
  • 2018-12-08
  • 2012-03-17
相关资源
最近更新 更多