在Python中测试抽象类

5

我使用Python(2.7)中的抽象类创建了一个类,现在我想通过Nose来测试这个类。如何在技术上实现?

这里我给出一个示例代码:

# -*- coding: utf-8 -*-
from abc import ABCMeta, abstractmethod, abstractproperty


class A(object):

    __metaclass__ = ABCMeta

    @abstractproperty
    def a(self):
        pass

    @abstractmethod
    def do(self, obj):
        pass
1个回答

5

您可以创建抽象类的子类并对子类进行测试。此外,在抽象方法被调用时,您可以使用NotImplementedError而不是pass

@abstractproperty
def a(self):
    raise NotImplementedError("Not implemented")

@abstractmethod
def do(self, obj):
    raise NotImplementedError("Not implemented")

如在Python异常文档中所述:

异常NotImplementedError

此异常是从RuntimeError派生而来的。在用户定义的基类中,当抽象方法需要派生类覆盖该方法时,应引发此异常。

然后您可以实现一个子类:

class B(A):
    def a(self):
        super(B, self).a()
    
    def do(self, obj):
        super(B, self).do(obj)

您可以这样测试:

@raises(NotImplementedError)
def abstractPropertyAShouldNotRun():
    B().a()

@raises(NotImplementedError)
def abstractMethodDoShouldNotRun():
    obj = []
    B().do(obj)

1
它仍然引发错误:TypeError: 无法实例化具有抽象方法a、do的抽象类A。是ABCMeta导致了这个错误吗? - Octavian
是的,你应该创建一个子类并直接测试它,而不是直接测试抽象类。我会更新我的答案。 - Anderson Vieira
@AndersonVieira 这个 @raises 是来自于 pytest 吗? - Gonzalo Garcia
2
@GonzaloGarcia,它来自nose(https://nose.readthedocs.io/en/latest/testing_tools.html)。我认为pytest有`pytest.raises`(https://docs.pytest.org/en/latest/assert.html#assertions-about-expected-exceptions)来检查是否引发了异常,但它不是一个注释。 - Anderson Vieira
这种方法不会增加代码覆盖率?pytest指出抽象类代码中引发NotImplementedError的行实际上并没有被覆盖到? - Derek
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接