Python 如何将覆盖率结果与tox相结合?

Python 如何将覆盖率结果与tox相结合?,python,code-coverage,coverage.py,tox,Python,Code Coverage,Coverage.py,Tox,对于我的包,我有执行环境相关的代码,如 if sys.version_info < (3, 0): pass # do something else: pass # do something else 和setup.cfg [metadata] description-file = README.md [tool:pytest] addopts = ./tests/ --doctest-modules --cov=./mpu --cov-report html:test

对于我的包,我有执行环境相关的代码,如

if sys.version_info < (3, 0):
   pass  # do something
else:
   pass  # do something else
和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文件似乎满足了我的要求,但覆盖范围仅限于其中一个测试环境。我已经看过了,但它不起作用。对于第一次运行,它似乎没有执行所有测试,因为测试覆盖率比以前低了很多。我猜医生没有被处决。第二轮,我得到

ERROR: InvocationError: '/home/moose/GitHub/mpu/.tox/py27/bin/coverage run --source=mpu/ setup.py test'
系统 错误 现在我得到了这个错误:

======================================================================
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
======================================================================
错误:test\u pd(unittest.loader.\u失败测试)
----------------------------------------------------------------------
导入错误:导入测试模块失败:测试\u pd
回溯(最近一次呼叫最后一次):
文件“/usr/lib/python3.6/unittest/loader.py”,第428行,在查找测试路径中
module=self.\u从\u name(name)获取\u module\u
文件“/usr/lib/python3.6/unittest/loader.py”,第369行,在“从”name“获取”模块中
__导入(名称)
文件“/home/moose/GitHub/mpu/tests/test_pd.py”,第8行,在
从mpu.pd导入示例
文件“/home/moose/GitHub/mpu/mpu/pd.py”,第10行,在
作为pd进口熊猫
文件“/home/moose/.local/lib/python3.6/site packages/pandas/_init__.py”,第42行,在
从pandas.core.api导入*
文件“/home/moose/.local/lib/python3.6/site packages/pandas/core/api.py”,第10行,在
从pandas.core.groupby.groupby导入石斑鱼
文件“/home/moose/.local/lib/python3.6/site packages/pandas/core/groupby/_init__.py”,第2行,在
从pandas.core.groupby.groupby导入(
文件“/home/moose/.local/lib/python3.6/site packages/pandas/core/groupby/groupby.py”,第49行,在
从pandas.core.frame导入数据帧
文件“/home/moose/.local/lib/python3.6/site packages/pandas/core/frame.py”,第74行,在
从pandas.core.series导入系列
文件“/home/moose/.local/lib/python3.6/site packages/pandas/core/series.py”,第80行,在
导入pandas.plotting.\u核心为gfx
文件“/home/moose/.local/lib/python3.6/site packages/pandas/plotting/__init__.py”,第11行,在
从pandas.plotting.\u核心导入箱线图
文件“/home/moose/.local/lib/python3.6/site packages/pandas/plotting/_core.py”,第45行,在
从pandas.plotting导入\u转换器
文件“/home/moose/.local/lib/python3.6/site packages/pandas/plotting/_converter.py”,第8行,在
将matplotlib.units作为单位导入
文件“/home/moose/.local/lib/python3.6/site packages/matplotlib/_init__.py”,第131行,在
从matplotlib.rcsetup导入默认参数,验证后端,循环
文件“/home/moose/.local/lib/python3.6/site packages/matplotlib/rcsetup.py”,第29行,在
从matplotlib.fontconfig_模式导入解析_fontconfig_模式
文件“/home/moose/.local/lib/python3.6/site packages/matplotlib/fontconfig_pattern.py”,第22行,在
从pyparsing导入(Literal、ZeroOrMore、Optional、Regex、StringEnd、,
文件“/home/moose/.local/lib/python3.6/site packages/pyparsing.py”,第943行,在
collections.MutableMapping.register(ParseResults)
文件“/usr/lib/python3.6/abc.py”,第158行,在寄存器中
如果为ISSUB类(子类,cls):
文件“/usr/lib/python3.6/abc.py”,第228行,在子检查中__
如果发布类(子类,SCL):
文件“/usr/lib/python3.6/abc.py”,第228行,在子检查中__
如果发布类(子类,SCL):
文件“/usr/lib/python3.6/typing.py”,第1154行,在子检查中__
返回super()。\uuuu子项检查(cls)
文件“/usr/lib/python3.6/abc.py”,第209行,在子检查中__
ok=cls.\子类钩子类(子类)
文件“/usr/lib/python3.6/typing.py”,第884行,在__
如果发布类(子类,SCL):
文件“/usr/lib/python3.6/typing.py”,第1154行,在子检查中__
返回super()。\uuuu子项检查(cls)
文件“/usr/lib/python3.6/abc.py”,第209行,在子检查中__
ok=cls.\子类钩子类(子类)
文件“/usr/lib/python3.6/typing.py”,第884行,在__
[...]
文件“/usr/lib/python3.6/typing.py”,第884行,在__
如果发布类(子类,SCL):
文件“/usr/lib/python3.6/abc.py”,第206行,在子检查中__
cls.\u abc\u负\u缓存中的elif子类:
文件“/usr/lib/python3.6/_-weakrefset.py”,第75行,包含__
在self.data中返回wr
RecursionError:比较中超出了最大递归深度

我假设您已经安装了
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

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

这个问题解决了吗?最后一节不清楚。您能澄清一下吗?不,它没有解决。我只是发现
--并行模式
必须在setup.py之前,这让人感到困惑,我想记下它。也许我应该从问题中删除这一部分。看看这个repo是否有任何帮助?啊,好吧,这是另一种方式。但我希望我可以用tox来完成。我更喜欢用
tox
作为执行所有与测试相关的命令。我认为模式是
begin,py{…},end
适用于此,但我不明白为什么/如何导致
错误:InvocationError
虽然我很欣赏您的答案(+1),但它似乎无法解决问题。请参阅我添加到问题中的错误。@Martintoma您发布的错误与
--cov append
选项无关-出于某种原因,测试是使用
unittest
而不是
pytest
运行的。您一定更改了其他原因。请添加您是如何发现
unittest
是问题的。我可以现在就开始:我直接呼叫了
coverage
,而不是使用
pytest
,让
pytest cov
呼叫coverage。谢谢!
======================================================================
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
[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