45

我有一个抽象基类:

class MyAbstractClass(object):
    __metaclass__ = ABCMeta

    @abstractproperty
    def myproperty(self): pass

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

是否有任何解决方法,或者我只需要接受 < 100% 的测试覆盖率?

当然,我可以删除这种ABCMeta用法并简单地使用基类 raise NotImpementedError,但我更喜欢前一种方法。

4

3 回答 3

60

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

class MyAbstractClass(object):
    __metaclass__ = ABCMeta

    @abstractproperty
    def myproperty(self):
       """ this property is too abstract to understand. """
于 2013-10-09T15:11:33.020 回答
39

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

@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

于 2012-02-09T14:12:00.940 回答
17

我在我的自定义跳过逻辑.coveragerc

[report]
exclude_lines =
    pragma: no cover
    @abstract

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

于 2016-12-22T13:48:35.787 回答