可以向夹具传递参数吗?

2 投票
2 回答
946 浏览
提问于 2025-04-18 18:33

我不是在说pytest定义的“Fixture参数化”,而是说你传递给一个函数(在这个例子中是fixture函数)的真实参数,这样可以让代码更模块化。

为了演示,这就是我的fixture:

@yield_fixture
def a_fixture(a_dependency):
    do_setup_work()
    yield
    do_teardown_work()
    a_dependency.teardown()

你可以看到,我的fixture依赖于一个叫做a_dependency的东西,而这个东西的teardown()也需要被调用。我知道在简单的用法中,我可以这样做:

@yield_fixture
def a_dependency():
    yield
    teardown()

@yield_fixture
def a_fixture(a_dependency):
    do_setup_work()
    yield
    do_teardown_work()

不过,虽然a_fixture的代码可以放在一个中心位置,供所有测试重用,但a_dependency的代码是特定于测试的,每个测试可能需要创建一个新的a_dependency对象。

我想避免把fixture和依赖的代码复制粘贴到我所有的测试中。如果这是普通的Python代码,我可以直接把a_dependency作为函数参数传递。那么,我该如何把这个对象传递给我的共享fixture呢?

2 个回答

0

好的,如果a_dependency确实需要是一个固定的东西,那为什么不试试两全其美的方法呢?毕竟,装饰器只是语法上的一种简化。

def a_dependency():
    # returns a context manager

a_dependency_fixture = yield_fixture(a_dependency)


@yield_fixture
def a_fixture():
    # here use a_dependency as a regular function
    with a_dependency() as dependency:
        do_setup_work()
        yield
        do_teardown_work()



def test_foo(a_dependency_fixture):
    # here use a_dependency as a fixture
    pass

我还没有确认这个方法是否真的有效,因为问题中的信息太笼统了,我无法从中得出一个可行的例子。如果你能提供更具体的信息,可能会更容易给出有用的答案。

0

我觉得你可能不想把 a_dependency 当作一个固定的东西(fixture),你只是想把它当成一个普通的函数。你是不是想要这样的东西呢?

def a_dependency():
    # returns a context manager


@yield_fixture
def a_fixture():
    with a_dependency() as dependency:
        do_setup_work()
        yield
        do_teardown_work()

撰写回答