簡體   English   中英

我如何在python 2.6中測試抽象方法

[英]how can i test an abstract method in python 2.6

我有一個抽象類:

import abc


class Hello(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def add(self, foo):
        pass

    @abc.abstractmethod
    def remove(self, foo):
        pass

我正在使用abc做抽象方法,所以,當我這樣做時:

hello = Hello()

並引發此錯誤: TypeError: Can't instantiate abstract class Hello with abstract methods add, remove

所以我可以測試這種類型錯誤:

self.assertRaises(Exception, Hello)  # but this only test the constructor and i can't get the 100% of code coverage. I need call the add method and the remove method

額外的問題:任何人都知道如何在python 2.6中斷言消息異常? (你不能使用with: for raise assertions。)

如何測試這種抽象方法以獲得100%的代碼覆蓋率?

如何創建抽象方法的文檔字符串而不是使用這里提到的passhttps://stackoverflow.com/a/19275908/469992 它還可以用於提供有關該方法在子類中應該執行的操作的一些信息。

abstract.py,

from abc import ABCMeta, abstractmethod                                            

class A(object):                                                                   
    __metaclass__ = ABCMeta                                                        

    @abstractmethod                                                                
    def some_method(self):                                                         
        "This method should ..."                                                   

class B(A):                                                                        
    def some_method(self):                                                         
        return 1

test_abstract.py,

import unittest                                                                    
import abstract                                                                    

class TestB(unittest.TestCase):                                                    
    def test(self):                                                                
        self.assertEqual(abstract.B().some_method(), 1)   

然后,使用python 2.6.8, nosetests --with-xcoverage輸出,

.
Name       Stmts   Miss  Cover   Missing
----------------------------------------
abstract       7      0   100%   
----------------------------------------------------------------------
Ran 1 test in 0.004s  

如何檢查類dict中的鍵:

>>> Hello.__dict__.has_key('__abstractmethods__')
True
>>> Hello.__dict__.has_key('__metaclass__')
True
>>>

您可以確保將Hello.__abstractmethods__定義的所有方法覆蓋到子類中。

>>> Hello.__abstractmethods__
frozenset(['add', 'remove'])
>>>

如果您錯過了在子類中重新定義任何這些方法,您仍會獲得錯過方法的TypeError:

TypeError: Can't instantiate abstract class Abs_Hello with abstract methods remove

或者像這樣測試:

 def check_all(abstract, sub_class):
    abs_method = abstract.__abstractmethods__
    for m in abs_method:
        if not isinstance(m, sub_class):
            raise TypeError("%s is not defined in subclass %s" % (m, repr(sub_class)))

你永遠不應該實例化一個抽象類。 您看到該錯誤的原因是設計原因。 抽象方法在它們的子類中實現,因為它定義了類不同的行為。 抽象類封裝了這些子類之間共享的行為。

為了說明,你想要這樣的東西:

class Language(Hello):

    def add(self, foo):
        self.baz.append(foo)

    def remove(self, foo):
        self.baz[foo] = None

注意Language如何從Hello繼承。 所以你應該測試抽象類的子類的實例,而不是抽象類本身。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM