我通过使用nose2attrib
插件进行发现和从nose1attrib
插件复制的一些代码来使用nose2,这使我可以装饰我的测试。
使用nose2attrib
插件
您将看到nose2attrib
插件允许在测试函数和类上定义自定义属性。
为此,您必须在定义测试函数后指定测试的属性。
class MyTestCase(unittest.TestCase):
def test_function(self):
self.assertEqual(1+1, 2)
test_function.custom_attr1 = True
test_function.custom_attr2 = ['foo', 'bar']
-A
然后,您可以通过指定或--attribute
作为命令行参数来运行一组过滤测试,nose2
以列出您要与测试套件匹配的属性。您甚至可以使用 or 的表达式命令行参数,它允许更复杂的 Python 表达式来匹配测试属性。-E
--eval-attribute
例如nose2 -v -A custom_attr1
,将运行所有具有custom_attr1
指定真值的测试。
使用装饰器指定测试属性
但这对我来说还不够好,因为我不喜欢在定义后在测试中定义这些属性的想法。我想改用装饰器,但nose2
没有内置的装饰器来做这件事。
我去了nose1attrib
插件的源代码并复制了attr
函数的源代码。
def attr(*args, **kwargs):
"""Decorator that adds attributes to classes or functions
for use with the Attribute (-a) plugin.
"""
def wrap_ob(ob):
for name in args:
setattr(ob, name, True)
for name, value in kwargs.iteritems():
setattr(ob, name, value)
return ob
return wrap_ob
我把它放到一个test/attrib_util.py
文件中。现在我可以使用装饰器指定属性。我上面的原始测试类代码可以转换为更简单的(IMO):
from test.attrib_util import attr
class MyTestCase(unittest.TestCase):
@attr('custom_attr1', custom_attr2=['foo', 'bar'])
def test_function(self):
self.assertEqual(1+1, 2)
您会注意到属性可以指定为 args 或 kwargs;所有 args 将获得默认值True
.
您甚至可以attr
在测试类或基类上使用此装饰器,这些属性将应用于其中定义的所有测试函数。这允许非常容易地分离单元测试和功能测试。
from test.attrib_util import attr
@attr('functional')
class FunctionalTestCase(unittest.TestCase):
pass
class MyFunctionalCase(FunctionalTestCase):
def test_function(self):
print 'this will be considered a "functional" test function'