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

时间:2017-02-13 08:31:38

标签: 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

我测试Reader但是(显然)我没有测试IReader pass指令被标记为未被测试覆盖。

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

1 个答案:

答案 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