始终执行带参数的测试装饰器

时间:2015-07-25 18:52:08

标签: python decorator pytest python-unittest python-decorators

我想要实现的是将某些测试所需的设置代码放在装饰器函数中。我故意避免 setUptearDown方法,因为它们被测试用例中的所有测试共享,而不是我正在寻找的。这更多的是个人偏好和学习兴趣,而不是直接的解决方案。

简化版代码:

# some import lines
from some.package import interceptor

class TestWhatever(unittest.TestCase):

    def test_simple_thing(self):
        # simple stuff

    def test_another_simple_thing(self):
        # more simple stuff

    @interceptor(arg1, arg2)
    def test_with_some_preparation_needed(self):
        # hey! Really cool stuff in here

    print('This will be executed with every test')

    @interceptor(arg1, arg2, namedarg1='foo', namedarg2='bar')
    def test_with_preparation_also(self):
        # the first decorator is executed
        # sure I'm not following Python's Zen

装饰者功能:

from wsgi_intercept import requests_intercept
from wsgi_intercept import add_wsgi_intercept


def interceptor(cityname, response, host='localhost', port=8000):
    requests_intercept.install()
    add_wsgi_intercept(host, port,
                       lambda: create_webservice(cityname, response))

    def decorator(test):

        def runtest(self):
            test(self)
            requests_intercept.uninstall()

        return runtest

    return decorator


def create_webservice(cityname, response):

    def app(environ, start_response):
        # a simple WSGI app

    return app

每个装饰器都是带参数的函数调用,因为我需要参数化设置。调用返回测试的真正装饰器。问题是它们就像放在函数定义之间的任何其他语句一样,因此它们会被执行。

测试装饰器的这个想法是否可行,我正在这样做?也许与数据提供商有关。

1 个答案:

答案 0 :(得分:0)

将您要执行的所有内容每次测试移动到runtest包装器中。创建interceptor()类对象时,decorator装饰器工厂和TestWhatever本身都会执行

def interceptor(cityname, response, host='localhost', port=8000):    
    def decorator(test):
        def runtest(self):
            requests_intercept.install()
            add_wsgi_intercept(
                host, port,
                lambda: create_webservice(cityname, response))
            test(self)
            requests_intercept.uninstall()
        return runtest    
    return decorator

请注意,普通模式仍然使用setUptearDown,并且仅 那些需要特定设置的测试那个班。您可以随时添加更多TestCase类,而无需为其他测试设置:

class TestWhateverWithSetup(unittest.TestCase):
    def setUp(self):
        requests_intercept.install()
        add_wsgi_intercept(
            host, port,
            lambda: create_webservice(cityname, response))

    def tearDown(self):
        requests_intercept.uninstall()

    def test_with_some_preparation_needed(self):
        # hey! Really cool stuff in here

    def test_with_preparation_also(self):
        # the first decorator is executed
        # sure I'm not following Python's Zen


class TestWhateverWithoutSetup(unittest.TestCase):
    def test_simple_thing(self):
        # simple stuff

    def test_another_simple_thing(self):
        # more simple stuff