我一直致力于从鼻子中的生成器获取测试的方法,以便为正在测试的特定迭代定制描述。只要我的生成器目标方法永远不会尝试从我的生成器类访问self
,我就能运行一些东西。我发现我的所有生成器目标实例都有一个公共测试类实例,而nose正在为生成器的每次测试运行生成一个测试类的一次性实例。这导致setUp
在每个测试实例鼻子上创建运行,但是从不在生成器上运行生成器目标所绑定的(当然,真正的问题是我无法看到如何绑定鼻子 - 为生成器目标创建实例)。这是我用来试图弄清楚这一切的代码(是的,我知道装饰器可能会更好作为一个可调用类,但是鼻子,至少我有1.2.1版本,明确检查测试是否是函数或者方法,所以一个可调用的类根本不会运行):
import inspect
def labelable_yielded_case(case):
argspec = inspect.getargspec(case)
if argspec.defaults is not None:
defaults_list = [''] * (len(argspec.args) - len(argspec.defaults)) + argspec.defaults
else:
defaults_list = [''] * len(argspec.args)
argument_defaults_list = zip(argspec.args, defaults_list)
case_wrappers = []
def add_description(wrapper_id, argument_dict):
case_wrappers[wrapper_id].description = case.__doc__.format(**argument_dict)
def case_factory(*factory_args, **factory_kwargs):
def case_wrapper_wrapper():
wrapper_id = len(case_wrappers)
def case_wrapper(*args, **kwargs):
args = factory_args + args
argument_list = []
for argument in argument_defaults_list:
argument_list.append(list(argument))
for index, value in enumerate(args):
argument_list[index][1] = value
argument_dict = dict(argument_list)
argument_dict.update(factory_kwargs)
argument_dict.update(kwargs)
add_description(wrapper_id, argument_dict)
return case(*args, **kwargs)
case_wrappers.append(case_wrapper)
case_wrapper.__name__ = case.__name__
return case_wrapper
return case_wrapper_wrapper()
return case_factory
class TestTest(object):
def __init__(self):
self.data = None
def setUp(self):
print 'setup', self
self.data = (1,2,3)
def test_all(self):
for index, value in enumerate((1,2,3)):
yield self.validate_equality(), index, value
def test_all_again(self):
for index, value in enumerate((1,2,3)):
yield self.validate_equality_again, index, value
@labelable_yielded_case
def validate_equality(self, index, value):
'''element {index} equals {value}'''
print 'test', self
assert self.data[index] == value, 'expected %d got %d' % (value, self.data[index])
def validate_equality_again(self, index, value):
print 'test', self
assert self.data[index] == value, 'expected %d got %d' % (value, self.data[index])
validate_equality_again.description = 'again'
当通过鼻子运行时,again
测试工作得很好,但使用装饰生成器目标的测试集都会失败,因为self.data is None
(因为setUp
因为实例而永远不会运行存储在闭包中的TestTest
不是由nose运行的实例。我试图让装饰器成为TestTest
的基类的实例成员,但是后来却抛出了关于将少量参数(没有self
)传递给未绑定labelable_yielded_case
的错误。有没有什么方法可以让我的工作(没有黑客的鼻子),或者我不能选择不能让屈服目标成为实例成员或者没有每个屈服测试的每个测试标签?
答案 0 :(得分:0)
修正了它(至少在这里的情况下,虽然我认为我得到了所有情况)。我不得不摆弄case_wrapper_wrapper
和case_wrapper
以使工厂返回附加到正确类的包装案例,但不以任何方式绑定到任何给定实例。我还有另一个代码问题,因为我在包装器包装器中构建参数dict,但后来没有将它传递给case。工作代码:
import inspect
def labelable_yielded_case(case):
argspec = inspect.getargspec(case)
if argspec.defaults is not None:
defaults_list = [''] * (len(argspec.args) - len(argspec.defaults)) + argspec.defaults
else:
defaults_list = [''] * len(argspec.args)
argument_defaults_list = zip(argspec.args, defaults_list)
case_wrappers = []
def add_description(wrapper_id, argument_dict):
case_wrappers[wrapper_id].description = case.__doc__.format(**argument_dict)
def case_factory(*factory_args, **factory_kwargs):
def case_wrapper_wrapper():
wrapper_id = len(case_wrappers)
def case_wrapper(*args, **kwargs):
argument_list = []
for argument in argument_defaults_list:
argument_list.append(list(argument))
for index, value in enumerate(args):
argument_list[index][1] = value
argument_dict = dict(argument_list)
argument_dict.update(kwargs)
add_description(wrapper_id, argument_dict)
return case(**argument_dict)
case_wrappers.append(case_wrapper)
case_name = case.__name__ + str(wrapper_id)
case_wrapper.__name__ = case_name
if factory_args:
setattr(factory_args[0].__class__, case_name, case_wrapper)
return getattr(factory_args[0].__class__, case_name)
else:
return case_wrapper
return case_wrapper_wrapper()
return case_factory
class TestTest(object):
def __init__(self):
self.data = None
def setUp(self):
self.data = (1,2,3)
def test_all(self):
for index, value in enumerate((1,2,3)):
yield self.validate_equality(), index, value
@labelable_yielded_case
def validate_equality(self, index, value):
'''element {index} equals {value}'''
assert self.data[index] == value, 'expected %d got %d' % (value, self.data[index])