我一直在做很多搜索,我不认为我真的找到了我一直在寻找的东西.我会尽力解释我想要做的事情,并希望有一个简单的解决方案,我很乐意学到新的东西.
这最终是我想要完成的: 使用nosetests,使用属性选择器插件装饰一些测试用例,然后在命令行调用期间使用-a开关执行符合条件的测试用例.然后,将执行的测试的属性值存储在外部位置.我正在使用的命令行调用如下:
nosetests \testpath\ -a attribute='someValue'
Run Code Online (Sandbox Code Playgroud)
我还创建了一个自定义的nosetest插件,它存储测试用例的属性,并将它们写入外部位置.我的想法是我可以选择一批测试,并且通过存储这些测试的属性,我可以稍后对这些结果进行过滤以用于报告目的.我通过使用类似于以下的代码覆盖"wantMethod"方法来访问我的插件中的方法属性:
def set_attribs(self, method, attribute):
if hasattr(method, attribute):
if not self.method_attributes.has_key(method.__name__):
self.method_attributes[method.__name__] = {}
self.method_attributes[method.__name__][attribute] = getattr(method, attribute)
def wantMethod(self, method):
self.set_attribs(method, "attribute1")
self.set_attribs(method, "attribute2")
pass
Run Code Online (Sandbox Code Playgroud)
我对几乎所有的测试都有用,除了一个案例,其中测试是使用"yield"关键字.发生的事情是生成的方法正在执行,但是每个生成的函数的方法属性都是空的.
以下是我想要实现的例子.下面的测试会检索一个值列表,并为每个值生成另一个函数的结果:
@attr(attribute1='someValue', attribute2='anotherValue')
def sample_test_generator(self):
for (key, value) in _input_dictionary.items()
f = partial(self._do_test, key, value)
f.attribute1='someValue'
yield (lambda x: f(), key)
def _do_test(self, input1, input2):
# Some code
Run Code Online (Sandbox Code Playgroud)
根据我的阅读,并且我认为我理解,当调用yield时,它将创建一个新的可调用函数,然后执行.我一直试图弄清楚如何从sample_test_generator方法中保留属性值,但我还没有成功.我以为我可以创建一个局部方法,然后将该属性添加到方法中,但没有运气.测试执行完全没有错误,似乎从我的插件的角度来看,方法属性不存在,因此它们不会被记录.
我意识到这是一个非常复杂的问题,但我想确保我想要实现的目标的背景是清楚的.我一直试图找到可以帮助我解决这个特殊情况的信息,但我觉得我现在遇到了绊脚石,所以我真的想请专家们提一些建议.
谢谢.
**更新**
在阅读了反馈并玩了一些之后,看起来如果我修改了lambda表达式,它将实现我正在寻找的东西.实际上,我甚至不需要创建部分功能:
def sample_test_generator(self):
for (key, value) in _input_dictionary.items()
yield (lambda: self._do_test)
Run Code Online (Sandbox Code Playgroud)
这种方法的唯一缺点是测试名称不会改变.当我正在玩更多时,它看起来像在nosetests中,当使用测试生成器时,它实际上会根据它包含的关键字更改结果中的测试名称.当我使用带有参数的lambda表达式时,也发生了同样的事情.
例如:
在nosetests插件中,当您访问测试用例名称时,它将显示为"sample_test_generator(value1)"
在这种情况下,测试用例名称为"sample_test_generator".在上面的示例中,如果字典中有多个值,则yield调用将多次发生.但是,测试名称将始终保留为"sample_test_generator".这并不像我获得唯一的测试名称那样糟糕,但是根本无法存储属性值.我会继续玩,但感谢到目前为止的反馈!
我忘了回来提供最后的最新消息,说明我最终是如何让这个工作起作用的,起初我有点困惑,在我看了一遍之后,我发现它已经有了如何识别测试:
我最初的实现假设每个被执行的测试都是通过插件基类的"wantMethod"调用完成的.当使用"yield"生成测试时,情况并非如此,因为此时测试方法已经通过了"wantMethod"调用.
但是,一旦通过"yeild"调用生成测试用例,它就会通过插件基类调用"startTest",这就是我最终能够成功存储属性的地方.
所以在一个坚果shell中,我的测试执行顺序如下所示:
nose - > wantMethod(method_name) - > yield - > startTest(yielded_test_name)
在我的startTest方法的覆盖中,我有以下内容:
def startTest(self, test):
# If a test is spawned by using the 'yield' keyword, the test names would be the parent test name, appended by the '(' character
# example: If the parent test is "smoke_test", the generated test from yield would be "smoke_test('input')
parent_test_name = test_name.split('(')[0]
if self.method_attributes.has_key(test_name):
self._test_attrib = self.method_attributes[test_name]
elif self.method_attributes.has_key(parent_test_name):
self._test_attrib = self.method_attributes[parent_test_name]
else:
self._test_attrib = None
Run Code Online (Sandbox Code Playgroud)
通过这个实现,以及我对wantMethod的覆盖,由父测试用例生成的每个测试也从父方法继承属性,这是我需要的.
再次感谢所有发送回复的人.这是一次非常学习的经历.
这能解决你的名字问题吗?
def _actual_test(x, y):
assert x == y
def test_yield():
_actual_test.description = "test_yield_%s_%s" % (5, 5)
yield _actual_test, 5, 5
_actual_test.description = "test_yield_%s_%s" % (4, 8) # fail
yield _actual_test, 4, 8
_actual_test.description = "test_yield_%s_%s" % (2, 2)
yield _actual_test, 2, 2
Run Code Online (Sandbox Code Playgroud)
重命名也幸存@attr下来。
| 归档时间: |
|
| 查看次数: |
425 次 |
| 最近记录: |