[英]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
。
我刚刚注意到@abstractmethod 装饰器。 由于它会阻止类被实例化,因此我不会引发NotImplementedError
。 看到这个另一个答案。
我只是将方法留空。 从语法上讲,一个文档字符串就足够了
class IReader(object):
@abstractmethod
def read(self):
"""Read data"""
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.