如何检查TDD中是否存在方法?

Hou*_*man 3 python unit-testing python-2.7

在严格的测试驱动开发方法中,每个步骤都需要事先进行测试.即使是一个类或它的方法的存在 - 严格来说 - 在实际创建之前要进行测试.

我有一个问题是进行写测试以查看方法是否存在.

class BasicTests(unittest.TestCase):

    def setUp(self):
        self.test = RandomGenClass()        

    def testRandomGenClassExists(self):
        """ Does the class exist? """        
        self.assert_(self.test is not None)

    def testMyMethodExists(self):
        """ Does MyMethod() exist?"""
        result = self.test.myMethod()
        self.assert_(result is not None)
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,如果该类不存在,Python就已经失败了.测试永远不会断言.有没有更好的方法来实现这一目标?

Hen*_*ter 5

类型的存在

有例外

如果没有定义类,尝试使用它将抛出一个非常具体的错误,所以解决这个问题的一种方法是捕获该错误(setUp大概是,或者在它首次使用的地方),然后就失败了.

def setUp(self):
    try:
        self.test = RandomGenClass()
    except NameError as e:
        pass # fail appropriately here.
Run Code Online (Sandbox Code Playgroud)

请记住,这可能会掩盖某些错误的原因:例如,如果RandomGenClass.__init__提出一个错误NameError.因此,对于您的情况,您可能需要更仔细地查看引发的错误,以确保它"RandomGenClass"是未定义的,而不是更深层次的名称.


globals()

所以,或许更好的方法来完成这个(对于你的用例,无论如何)是通过查找globals()你想要使用的类的名称返回的字典,但我个人认为这有点丑陋,更容易出问题.它没有掩盖其他错误的问题.

if not 'RandomGenClass' in globals():
    pass # fail appropriately
Run Code Online (Sandbox Code Playgroud)

hasattr

如果类存在于其他模块中(可能,但不一定是这种情况),我们可以使用hasattr与我们测试方法相同的方式使用模块对象(如下所示).这可能是整体上最干净的方式.

import some_module
if not hasattr(some_module, 'ClassName'):
    pass # fail appropriately
Run Code Online (Sandbox Code Playgroud)

根据类的起源,您实际上可能能够更早地捕获它.如果要从定义它们的任何位置导入类,则可以只显式导入它们,并查找ImportError是否未定义类.


方法的存在

至于方法测试,那部分很容易.一旦知道该类存在并且您有一个实例,就可以hasattr用来确定是否为该对象定义了给定的名称.

if hasattr(self.test, 'method_name'):
    result = self.test.method_name()
Run Code Online (Sandbox Code Playgroud)

当然,您也可以使用与测试类的存在几乎完全相同的方式执行此操作:继续执行此操作,并在错误爆发时捕获错误.同样,这个需要某种验证,你正在捕获的属性错误实际上是你正在寻找的属性错误.

try:
    result = self.test.myMethod()
except AttributeError as e:
    pass # fail appropriately
Run Code Online (Sandbox Code Playgroud)