繁体   English   中英

Python 接口模式和单元测试代码覆盖率

[英]Python interface pattern and unit test code coverage

我用了一个Python项目工作unittest与测试一起coverage代码覆盖。
我广泛使用接口模式,我注意到整体代码覆盖率受“非测试接口”的影响很大。
考虑以下:

class IReader(object):
    @abstractmethod
    def read(self):
        pass


class Reader(IReader):
    def read(self):
        # whatever

我测试Reader但(显然)我不测试IReader因此pass指令被标记为未包含在测试中。

有没有办法忽略coverage的接口?
由于这是我的第一个 python 项目之一,我这样做是完全错误的吗?

我真的不明白将这个read方法定义为 pass 作为单个指令的意义。 如果你不需要它,让它引发NotImplementedError

class IReader(object):
    @abstractmethod
    def read(self):
        raise NotImplementedError

正如 文档中所指定 ,抽象方法可以有一个由super()子项使用的实现。 但在你的情况下,它什么都不做。 因此,除非您有充分的理由,否则不妨让它引发NotImplementedError

(可以说,一个很好的理由可能是一种模式,即您的所有孩子出于某种原因都调用super().my_method() ,因此您需要为抽象类中的所有方法实现一个实现。)

如何从覆盖率报告中排除抽象方法

无论如何,测试覆盖率只是您构建的一个指标:您要测试的代码部分是您实际测试的部分。 定义“您要测试的代码”取决于您。

如果您对此感兴趣,您可以添加一个测试来检查抽象方法是否返回NotImplementedError或仅pass es。

或者您可能认为(这似乎是合理的)测试这是没有意义的,在这种情况下,从覆盖率报告中排除该方法#pragma: no cover似乎是要走的路:

class IReader(object):  #pragma: no cover
    @abstractmethod
    def read(self):
        pass

上面链接的文档页面显示了如何排除所有将其添加到配置文件的NotImplementedError方法:

[report]
exclude_lines =
    pragma: no cover
    raise NotImplementedError

这样您就不必为每个抽象方法添加pragma


2020年编辑

我刚刚注意到@abstractmethod 装饰器。 由于它会阻止类被实例化,因此我不会引发NotImplementedError 看到这个另一个答案。

我只是将方法留空。 从语法上讲,一个文档字符串就足够了

class IReader(object):
    @abstractmethod
    def read(self):
        """Read data"""

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM