从覆盖报告中排除抽象属性

Posted

技术标签:

【中文标题】从覆盖报告中排除抽象属性【英文标题】:Excluding abstractproperties from coverage reports 【发布时间】:2012-03-01 10:38:15 【问题描述】:

我有一个抽象基类:

class MyAbstractClass(object):
    __metaclass__ = ABCMeta

    @abstractproperty
    def myproperty(self): pass

但是当我在我的项目上运行鼻子测试(覆盖范围)时,它抱怨属性 def 行未经测试。它实际上无法被测试(AFAIK),因为抽象类的实例化将导致引发异常..

是否有任何解决方法,或者我只需要接受

当然,我可以删除 ABCMeta 的用法并简单地让基类提升 NotImpementedError,但我更喜欢前一种方法。

【问题讨论】:

【参考方案1】:

没有办法完全按照您的方式排除抽象属性,但是如果您稍作更改,就可以。让您的抽象属性引发错误:

@abstractproperty
def myproperty(self): 
    raise NotImplementedError

然后您可以指示 coverage.py 忽略引发 NotImplementedError 的行。创建一个 .coveragerc 文件,并在其中放入:

[report]
exclude_lines =
    # Have to re-enable the standard pragma
    pragma: no cover

    # Don't complain if tests don't hit defensive assertion code:
    raise NotImplementedError

有关您可能希望始终忽略的行类型的更多想法,请参阅:http://nedbatchelder.com/code/coverage/config.html

【讨论】:

我最终在 IRC 上发现了 #pragma: no cover 并使用了该内联。我不喜欢在抽象属性中实现(即使它只是 raise NotImplementedError,因为它似乎违背了目的)。 等待:您可以在每个抽象属性上添加“#pragma: no cover”注释,但是您不能将正文从 pass 更改为“raise NotImplementedError”?对于每个人来说,我猜......很高兴你找到了你喜欢的解决方案。 我绝对同意这也不是最佳解决方案,但我更喜欢使用这样的内联指令来改变抽象基类模块的预期用途和好处.. 另一种选择是将文档字符串添加到您的抽象方法或属性中,而不是使用pass。这还有一个额外的好处,那就是拥有有关抽象方法/属性的预期行为方式的文档。 @WesleyBaugh:可悲的是,当您启用分支覆盖时,覆盖工具仍然会报告此类注释的空方法(无论如何应该默认启用)。【参考方案2】:

对我来说,最好的解决方案是@Wesley 在他对已接受答案的评论中提到的,特别是用抽象属性的文档字符串替换“pass”,例如:

class MyAbstractClass(object):
    __metaclass__ = ABCMeta

    @abstractproperty
    def myproperty(self):
       """ this property is too abstract to understand. """

【讨论】:

【参考方案3】:

我的.coveragerc 中有自定义跳过逻辑:

[report]
exclude_lines =
    pragma: no cover
    @abstract

这样,所有抽象方法和抽象属性都被标记为已跳过。

【讨论】:

与毒物配合得很好!

以上是关于从覆盖报告中排除抽象属性的主要内容,如果未能解决你的问题,请参考以下文章

nyc (istanbul) 从覆盖率报告中排除测试代码

如何从 phpunit 覆盖率报告中排除目录

有没有办法从业力覆盖文本报告器结果中排除所有 100% 或阈值的文件?

使用 Cobertura 从代码覆盖中排除方法

如何从android项目中的jacoco测试覆盖率报告中排除方法

从 Karma 覆盖率报告中排除 angular.js、angular-ui-router.js、angular-mocks.js 等导入文件