Python装饰器:测试前运行装饰器

时间:2017-03-27 18:42:00

标签: python unit-testing python-decorators

我想在某些测试中添加一个运行录像机的装饰器,如下所示:

@decorators.video(self)
def test_1234(self):
    ...

我无法将自变量传递给装饰器,因为它需要一些属性。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

正统答案通常很好,但对于装饰者,你应该使用functools.wraps函数,如下例所示:

from functools import wraps

def enable_video(fn)
    '''Decorate the function to start video, call the function, stop video.'''
    @wraps(fn)
    def inner(*args, **kwargs): 
    # could be just `def inner(self):` if only intended to use
    # with methods without arguments and keyword arguments
        do_stuff_before()
        fn(*args, **kwargs)
        do_stuff_after()
    return inner

它将保留原始文档字符串,原始函数名称(以及更多)。您可以在Python docs中了解有关它的更多信息。

然后,假设前面的代码在decorators模块中,您应该按如下方式使用它:

class MyTestCase(unittests.TestCase);
    @decorators.enable_video
    def testSomeVideoFunction(self):
        do_test_stuff()

请注意,在代码示例中,它只是@decorators.enable_video不是 @decorators.enable_video(self)。就像jonrsharpe对你的问题的评论一样,在装饰时没有提到self

答案 1 :(得分:0)

您确定需要self参考吗?

更常见的是你会做这样的事情

def enable_video(fn):
    '''decorate the test function so it starts the video, runs the test, and stop the video'''   
    def video_aware_test(self_refrence):
       start_video_recorder()
       try:
          fn()
       finally:
          stop_video_recorder()
    return video_aware_test

你可以这样申请:

 @enable_video
 def test_something(self)

如果由于某种原因,装饰者实际上需要自我引用,你可以看到你抓住它的位置。此版本不包括以任何方式配置录像机,以及您使用类而不是函数装饰器并将配置作为参数传递。