我如何(或能够)从鼻子测试中调用生成器以由鼻子处理?

发布于 2025-01-03 17:08:42 字数 643 浏览 1 评论 0原文

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

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() 备份生成器鼻子。我尝试过从 test_foo() 中的 run() 返回生成器,但这也不好。这可能吗?

I'm trying to create a genericized data driven test handler that I can call from my nose tests. My test file would look like:

import ScenarioHandler

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

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

ScenarioHandler would be something like this:

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

The problem I'm running in to is that I can't figure out how to bubble the generator from ScenarioHandler.run() back up to nose. I've tried returning the generator from run() in test_foo(), and that was no good either. Is this even possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

叹沉浮 2025-01-10 17:08:42

我不知道这个鼻子的东西到底是如何工作的。

但你给出的例子不能工作。

您有调用树

test_foo() -> 运行()

由于 run() 返回一个生成器,该生成器直到迭代开始才启动,因此您应该这样做。

要么做

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

要么更好,因为nose已经通过使用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 将测试封装在类中。

I don't know how this nose stuff works exactly.

But your given example cannot work.

You have the call tree

test_foo() -> run().

As run() returns a generator which doesn't start until iteration starts, you should do so.

Either do

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

or better, as nose provides this already by explicitly testing the flags of the given function with 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

in order to have nose make these calls.

(There could have been an even shorter thing, i. e. to use

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

which, alas, doesn't work because methods are obviously not correctly detected as valid call targets.)

But you could add a "test maker" to your class.

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

So you can do

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

But probably nose provides better ways to encapsulate your tests in classes by subclassing TestCase and TestSuite.

意犹 2025-01-10 17:08:42

为什么不使用类似的东西:

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

另请参阅我的答案中的add_tests(generator)函数。

Why don't you use something like:

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

See also add_tests(generator) function from my answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文