我在python项目中使用unittest
进行测试,并使用coverage
进行代码覆盖。
我广泛使用界面模式,我注意到整体代码覆盖率很大程度上受到"未经测试的界面的影响"。
请考虑以下事项:
class IReader(object):
@abstractmethod
def read(self):
pass
class Reader(IReader):
def read(self):
# whatever
我测试Reader
但是(显然)我没有测试IReader
pass
指令被标记为未被测试覆盖。
有没有办法忽略coverage
的接口?
由于这是我的第一个python项目之一,我这样做完全错了吗?
答案 0 :(得分:5)
我并没有真正意识到将这个read
方法定义为pass作为单个指令。如果您不需要它,请让它NotImplementedError
。
class IReader(object):
@abstractmethod
def read(self):
raise NotImplementedError
如the docs中所述,抽象方法可以具有super()
的子项使用的实现。但在你的情况下,它什么也没做。因此,除非你有充分的理由,否则你也可以提出NotImplementedError
。
(可以说,一个很好的理由可能是所有孩子因某种原因调用super().my_method()
的模式,所以你需要为抽象类中的所有方法实现一个实现。)
无论如何,测试覆盖率只是您构建的指标:您要测试的代码中您实际测试的部分。定义“您要测试的代码”取决于您。
如果您对此感兴趣,可以添加测试以检查抽象方法是返回NotImplementedError
还是pass
es。
或者你可能认为(这似乎是合理的)测试这是毫无意义的,在这种情况下excluding来自覆盖率报告#pragma: no cover
的方法似乎是要走的路:
class IReader(object): #pragma: no cover
@abstractmethod
def read(self):
pass
上面链接的文档页面显示了如何排除将此添加到配置文件中的所有NotImplementedError
方法:
[report]
exclude_lines =
pragma: no cover
raise NotImplementedError
这样您就不必为每个抽象方法添加pragma
。