是否可以使用 python 装饰器将特定的单元测试指向正在测试的不同实例?
Is it possible to use python decorators to direct specific unit tests toward different instances of what is being tested?
我有一个包含 XML 个字符串的 class。这些是我的模型。
class ContainerForStringXMLs():
def __init__(self):
pass
@staticmethod
def get_model1(self):
return """I'm a long string called model1"""
@staticmethod
def get_model2(self):
return """I'm a long string called model2"""
我有一个基础测试 class,它让我可以访问其他测试中的模型(以及其他一些在这里不重要的东西)
class BaseTest(unittest.TestCase):
def setUp(self, model='model1'):
self.model=model
if self.model == 'model1':
self.test_model = ContainerForStringXMLs.model1()
elif self.model == 'model2':
self.test_model = ContainerForStringXMLs.model2()
def tearDown(self):
del self.model
del self.test_model
我的实际测试 class 看起来像这样:
class TestClass(BaseTest):
def __init__(self):
pass
def test_on_model1(self):
"""
I want to perform this test on model1
"""
print self.test_model ##would return model 1
def test_on_model2(self):
"""
I want to perform this test on model 2
"""
print self.testmodel2
我要执行的测试是完全相同的测试,但模型不同,因此我从 xml 中提取的值在每种情况下都会不同。我的问题是:是否有一种很好的 pythonic 方式可以在 TestClass 的模型之间切换?我在想也许是装饰师或某种?
如果我能够使用类似下面的东西来选择我将测试指向哪个模型,那就太好了:
class TestClass(BaseTest):
def __init__(self):
pass
@testmodel1
def test_on_model1(self):
"""
I want to perform this test on model1
"""
print self.test_model ##would return model 1
@testmodel2
def test_on_model2(self):
"""
I want to perform this test on model 2
"""
print self.testmodel2
这种行为可能吗?
“XML 字符串”class 按原样在 models.py
中。
测试助手(基础 class 和装饰器)在 testutils.py
:
import unittest
import functools
import models
class BaseTestCase(unittest.TestCase):
def setUp(self, model='model1'):
self.model_loader = models.ContainerForStringXMLs
self.model = model
@property
def model_contents(self):
return getattr(
self.model_loader, 'get_' + self.model)(self.model_loader)
def use_model(model):
"""Make BaseTestCase-aware test use particular model."""
def _wrapper(func):
@functools.wraps(func)
def _inner(self):
orig = self.model
self.model = model
func(self)
self.model = orig
return _inner
return _wrapper
use_model
是一个采用模型名称 (model
) 的装饰器,并且
暂时设置 self.model
为测试方法。 model_contents
是从 ContainerForStringXMLs
获取 XML 字符串的 属性
当前 self.model
.
因为 get_model1
和 get_model2
是采用 self
的静态方法
(在你的例子中),在 model_contents
我通过 ContainerForStringXMLs
class 为 self
(这不是特别好)。如果那不是什么
你想要,将 (self.model_loader)
更改为其他内容(并且,
当然,更改 ContainerForStringXMLs
中的 get_*
方法以匹配
你称呼他们的方式)。鉴于这是一个小问题,我只是假设
只有测试和 BaseTest
可以修改。
在test_models.py
中有两个测试用例:
from testutils import BaseTestCase, use_model
class TwoModelsWithDefaultModelTest(BaseTestCase):
def setUp(self):
BaseTestCase.setUp(self, model='model2')
@use_model('model1')
def test_first_model(self):
self.assertEqual(self.model, 'model1')
self.assertEqual(
self.model_contents,
"I'm a long string called model1")
def test_second_model(self):
self.assertEqual(self.model, 'model2')
self.assertEqual(
self.model_contents,
"I'm a long string called model2")
@use_model('model1')
def test_first_model_again(self):
self.assertEqual(self.model, 'model1')
self.assertEqual(
self.model_contents,
"I'm a long string called model1")
def test_second_model_again(self):
self.assertEqual(self.model, 'model2')
self.assertEqual(
self.model_contents,
"I'm a long string called model2")
class TwoModelsTestWithoutExplicitSetUp(BaseTestCase):
@use_model('model1')
def test_first_model(self):
self.assertEqual(self.model, 'model1')
self.assertEqual(
self.model_contents,
"I'm a long string called model1")
@use_model('model2')
def test_second_model(self):
self.assertEqual(self.model, 'model2')
self.assertEqual(
self.model_contents,
"I'm a long string called model2")
def test_first_model_again(self):
self.assertEqual(self.model, 'model1')
self.assertEqual(
self.model_contents,
"I'm a long string called model1")
@use_model('model2')
def test_second_model_again(self):
self.assertEqual(self.model, 'model2')
self.assertEqual(
self.model_contents,
"I'm a long string called model2")
TwoModelsWithDefaultModelTest
调用 BaseTestCase.setUp
将 self.model
设置为 'model2'
用于不使用的测试
use_model
装饰器。 TwoModelsTestWithoutExplicitSetUp
使用
BaseTestCase.setUp
的默认实现没有改变
model
参数默认,所以默认 self.model
是 'model1'
.
根据 print
语句判断,您使用 Python 2. 您
should 制作
ContainerForStringXMLs
继承自 object
.
我有一个包含 XML 个字符串的 class。这些是我的模型。
class ContainerForStringXMLs():
def __init__(self):
pass
@staticmethod
def get_model1(self):
return """I'm a long string called model1"""
@staticmethod
def get_model2(self):
return """I'm a long string called model2"""
我有一个基础测试 class,它让我可以访问其他测试中的模型(以及其他一些在这里不重要的东西)
class BaseTest(unittest.TestCase):
def setUp(self, model='model1'):
self.model=model
if self.model == 'model1':
self.test_model = ContainerForStringXMLs.model1()
elif self.model == 'model2':
self.test_model = ContainerForStringXMLs.model2()
def tearDown(self):
del self.model
del self.test_model
我的实际测试 class 看起来像这样:
class TestClass(BaseTest):
def __init__(self):
pass
def test_on_model1(self):
"""
I want to perform this test on model1
"""
print self.test_model ##would return model 1
def test_on_model2(self):
"""
I want to perform this test on model 2
"""
print self.testmodel2
我要执行的测试是完全相同的测试,但模型不同,因此我从 xml 中提取的值在每种情况下都会不同。我的问题是:是否有一种很好的 pythonic 方式可以在 TestClass 的模型之间切换?我在想也许是装饰师或某种?
如果我能够使用类似下面的东西来选择我将测试指向哪个模型,那就太好了:
class TestClass(BaseTest):
def __init__(self):
pass
@testmodel1
def test_on_model1(self):
"""
I want to perform this test on model1
"""
print self.test_model ##would return model 1
@testmodel2
def test_on_model2(self):
"""
I want to perform this test on model 2
"""
print self.testmodel2
这种行为可能吗?
“XML 字符串”class 按原样在 models.py
中。
测试助手(基础 class 和装饰器)在 testutils.py
:
import unittest
import functools
import models
class BaseTestCase(unittest.TestCase):
def setUp(self, model='model1'):
self.model_loader = models.ContainerForStringXMLs
self.model = model
@property
def model_contents(self):
return getattr(
self.model_loader, 'get_' + self.model)(self.model_loader)
def use_model(model):
"""Make BaseTestCase-aware test use particular model."""
def _wrapper(func):
@functools.wraps(func)
def _inner(self):
orig = self.model
self.model = model
func(self)
self.model = orig
return _inner
return _wrapper
use_model
是一个采用模型名称 (model
) 的装饰器,并且
暂时设置 self.model
为测试方法。 model_contents
是从 ContainerForStringXMLs
获取 XML 字符串的 属性
当前 self.model
.
因为 get_model1
和 get_model2
是采用 self
的静态方法
(在你的例子中),在 model_contents
我通过 ContainerForStringXMLs
class 为 self
(这不是特别好)。如果那不是什么
你想要,将 (self.model_loader)
更改为其他内容(并且,
当然,更改 ContainerForStringXMLs
中的 get_*
方法以匹配
你称呼他们的方式)。鉴于这是一个小问题,我只是假设
只有测试和 BaseTest
可以修改。
在test_models.py
中有两个测试用例:
from testutils import BaseTestCase, use_model
class TwoModelsWithDefaultModelTest(BaseTestCase):
def setUp(self):
BaseTestCase.setUp(self, model='model2')
@use_model('model1')
def test_first_model(self):
self.assertEqual(self.model, 'model1')
self.assertEqual(
self.model_contents,
"I'm a long string called model1")
def test_second_model(self):
self.assertEqual(self.model, 'model2')
self.assertEqual(
self.model_contents,
"I'm a long string called model2")
@use_model('model1')
def test_first_model_again(self):
self.assertEqual(self.model, 'model1')
self.assertEqual(
self.model_contents,
"I'm a long string called model1")
def test_second_model_again(self):
self.assertEqual(self.model, 'model2')
self.assertEqual(
self.model_contents,
"I'm a long string called model2")
class TwoModelsTestWithoutExplicitSetUp(BaseTestCase):
@use_model('model1')
def test_first_model(self):
self.assertEqual(self.model, 'model1')
self.assertEqual(
self.model_contents,
"I'm a long string called model1")
@use_model('model2')
def test_second_model(self):
self.assertEqual(self.model, 'model2')
self.assertEqual(
self.model_contents,
"I'm a long string called model2")
def test_first_model_again(self):
self.assertEqual(self.model, 'model1')
self.assertEqual(
self.model_contents,
"I'm a long string called model1")
@use_model('model2')
def test_second_model_again(self):
self.assertEqual(self.model, 'model2')
self.assertEqual(
self.model_contents,
"I'm a long string called model2")
TwoModelsWithDefaultModelTest
调用 BaseTestCase.setUp
将 self.model
设置为 'model2'
用于不使用的测试
use_model
装饰器。 TwoModelsTestWithoutExplicitSetUp
使用
BaseTestCase.setUp
的默认实现没有改变
model
参数默认,所以默认 self.model
是 'model1'
.
根据 print
语句判断,您使用 Python 2. 您
should 制作
ContainerForStringXMLs
继承自 object
.