总是执行带参数的测试装饰器
Test decorators with arguments are always executed
我想要实现的是将某些测试所需的设置代码放入装饰器函数中。我 故意避免 setUp
和 tearDown
方法,因为它们由测试用例中的所有测试共享,而这不是我要找的。这更多的是个人喜好和学习兴趣的问题,而不是寻求直接的解决方案。
代码的简化版本:
# 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
每个装饰器都是一个带参数的函数调用,因为我需要对设置进行参数化。调用 returns 测试的真正装饰器。问题是它们就像放置在函数定义之间的任何其他语句一样,因此它们会被执行。
像我这样用参数测试装饰器的想法可行吗?也许有了数据提供商,这将成为可能。
将每个测试要执行的所有内容移动到runtest
包装器中。 interceptor()
装饰器工厂和 decorator
本身都会在 创建 TestWhatever
class 对象时执行 :
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
注意,normal模式仍然使用setUp
和tearDown
,并且只使用那些需要在 class 中进行特定设置的测试。您可以随时添加更多 TestCase
classes 而无需为其他测试设置:
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
我想要实现的是将某些测试所需的设置代码放入装饰器函数中。我 故意避免 setUp
和 tearDown
方法,因为它们由测试用例中的所有测试共享,而这不是我要找的。这更多的是个人喜好和学习兴趣的问题,而不是寻求直接的解决方案。
代码的简化版本:
# 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
每个装饰器都是一个带参数的函数调用,因为我需要对设置进行参数化。调用 returns 测试的真正装饰器。问题是它们就像放置在函数定义之间的任何其他语句一样,因此它们会被执行。
像我这样用参数测试装饰器的想法可行吗?也许有了数据提供商,这将成为可能。
将每个测试要执行的所有内容移动到runtest
包装器中。 interceptor()
装饰器工厂和 decorator
本身都会在 创建 TestWhatever
class 对象时执行 :
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
注意,normal模式仍然使用setUp
和tearDown
,并且只使用那些需要在 class 中进行特定设置的测试。您可以随时添加更多 TestCase
classes 而无需为其他测试设置:
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