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

Ste*_*ini 3 python unit-testing code-coverage python-unittest

我正在使用python项目unittest进行测试以及coverage代码覆盖.
我广泛使用接口模式,我注意到整体代码覆盖率很大程度上受"未经测试的接口"的影响.
考虑以下:

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


class Reader(IReader):
    def read(self):
        # whatever
Run Code Online (Sandbox Code Playgroud)

我测试Reader但(显然)我没有测试,IReader因此pass指令被标记为未被测试覆盖.

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

Jér*_*ôme 5

我并没有真正意识到将这个read方法定义为pass作为单个指令.如果你不需要它,那就加油吧NotImplementedError.

class IReader(object):
    @abstractmethod
    def read(self):
        raise NotImplementedError
Run Code Online (Sandbox Code Playgroud)

如文档中所指定的,抽象方法可以具有子项使用的实现super().但在你的情况下,它什么也没做.因此,除非你有充分的理由,否则你不妨提出它NotImplementedError.

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

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

无论如何,测试覆盖率只是您构建的指标:您要测试的代码中您实际测试的部分.定义"您要测试的代码"取决于您.

如果您对此感兴趣,可以添加一个测试来检查抽象方法是否返回,NotImplementedError或者只是passes.

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

class IReader(object):  #pragma: no cover
    @abstractmethod
    def read(self):
        pass
Run Code Online (Sandbox Code Playgroud)

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

[report]
exclude_lines =
    pragma: no cover
    raise NotImplementedError
Run Code Online (Sandbox Code Playgroud)

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