python unittest:不能调用装饰测试

时间:2011-06-10 21:17:27

标签: python unit-testing decorator

我有一个非常大的测试套件,我装饰了一些test_ *函数。现在我无法通过./test.py MySqlTestCase.test_foo_double调用它们,python3.2抱怨:ValueError: no such test method in <class '__main__.MySqlTestCase'>: result。我的装饰器代码如下所示:

def procedure_test(procedure_name, arguments_count, returns):

    '''Decorator for procedure tests, that simplifies testing whether procedure
    with given name is available, whether it has given number of arguments
    and returns given value.'''

    def decorator(test):
        def result(self):
            procedure = self.db.procedures[self.case(procedure_name)]
            self.assertEqual(len(procedure.arguments), arguments_count)
            self.assertEqual(procedure.returns, 
                             None if returns is None else self.case(returns))
            test(self, procedure)
        return result
    return decorator

和测试方法:

@procedure_test('foo_double', 0, 'integer')
def test_foo_double(self, procedure):
    self.assertEqual(procedure.database, self.db)
    self.assertEqual(procedure.sql, 'RETURN 2 * value')
    self.assertArguments(procedure, [('value', 'int4')])

4 个答案:

答案 0 :(得分:7)

我认为问题在于装饰函数的名称不同,并且它不满足将模式视为测试方法。

使用functools.wrap来装饰decorator可以解决您的问题。更多信息here

答案 1 :(得分:1)

基于this帖子:

你可以这样做:

def decorator(test):
    def wrapper(self):
        # do something interesting
        test(self)
        # do something interesting
    wrapper.__name__ = test.__name__
    return wrapper

与使用@functools.wrap

的方法相比,此解决方案有两个优点
  • 无需导入任何内容
  • 在创建装饰器时不需要知道测试名称

由于此解决方案的第二个特性,可以为许多测试创建装饰器。

答案 2 :(得分:0)

这有助于我:

from functools import wraps

...

@wraps(procedure_name)
def decorator(test):

答案 3 :(得分:0)

这是解决此问题的简单方法。

from functools import wraps

def your_decorator(func):
    @wraps(func)
    def wrapper(self):
        #Do Whatever
        return func(self)
    return wrapper

class YourTest(APITestCase):
    @your_decorator
    def example(self):
        #Do your thing