我如何(或可以)从鼻子测试中得到一个被鼻子处理的发生器?

时间:2012-02-07 17:13:07

标签: python generator nose

我正在尝试创建一个通用的数据驱动测试处理程序,我可以从我的鼻子测试中调用它。我的测试文件看起来像:

import ScenarioHandler

def test_foo():
    scenario = ScenarioHandler(__test_foo, [1, 2])
    scenario.run()

def __test_foo(var):
    assert var % 2 == 0, 'Odd!'

ScenarioHandler会是这样的:

class ScenarioHandler(object):

    def __init__(self, test, args):
        self.test = test
        self.args = args

    def run(self):
        for arg in self.args:
            yield self.test, arg

我遇到的问题是我无法弄清楚如何将发生器从ScenarioHandler.run()冒泡回鼻子。我已经尝试从run()中的test_foo()返回生成器,这也不好。这甚至可能吗?

2 个答案:

答案 0 :(得分:0)

为什么不使用以下内容:

def test_foo():
    for var in [1, 2]:
        yield __test_foo, var

另请参阅my answer中的add_tests(generator)函数。

答案 1 :(得分:0)

我不知道这个nose内容是如何运作的。

但是你给出的例子不起作用。

你有调用树

test_foo() - > run()

run()返回一个在迭代开始之前没有启动的生成器,你应该这样做。

要么

def test_foo():
    scenario = ScenarioHandler(__test_foo, [1, 2])
    for f, a in scenario.run():
        f(a)

或更好,因为鼻子已经通过func.func_code.co_flags & CO_GENERATOR != 0显式测试给定函数的标志来提供这个,

def test_foo():
    scenario = ScenarioHandler(__test_foo, [1, 2])
    for f, a in scenario.run():
        yield f, a

nose进行这些调用。

可能是一个更短的东西,即使用

test_meth = ScenarioHandler(__test_foo, [1, 2]).run

,唉,不起作用,因为显然没有正确地将方法检测为有效的呼叫目标。)

但你可以为你的班级添加一个“测试工具”。

# as method:
    def make_test(self):
        def test_generator():
            for item in self.run():
                yield item
        return test_generator

所以你可以做到

test_foo = ScenarioHandler(__test_foo, [1, 2]).make_test()

但可能nose通过子类化TestCaseTestSuite提供了更好的方法来将测试封装在类中。