更改在 pytest 中调用固定装置的方式

Change a way fixtures are called in pytest

我在 conftest.py

有固定装置
@pytest.fixture(scope="function", autouse=True)
@pytest.mark.usefixtures
def pause_on_assert():
    yield
    if hasattr(sys, 'last_value') and isinstance(sys.last_value, AssertionError):
        tkinter.messagebox.showinfo(sys.last_value)

类似地,conftest.py 中还有许多其他修复程序,范围为 sessionmodule

我的测试用例是这样的

test.py

@pytest.fixture(scope="function", autouse=True)
def _wrapper:
    print("pre condition")
    yield
    print("post condition")

def test_abc():
    assert 1==0

问题是我希望我的夹具在 conftest.py 到 运行 之前 yield 我的测试用例

如何更改夹具执行方式的顺序

这里是 运行 在打印 "B".

的测试函数之前打印 "A" 的 conftest.py 函数的示例

cd 到父目录,在本例中是 py_tests 和 运行.

pytest -s -v

输出为:

A
setting up
B
PASSED

目录结构:

py_tests
 -conftest.py
 -tests
  --tests.py

文件:

conftest.py

import pytest

@pytest.fixture(scope="function")
def print_one():
    print("\n")
    print("A")

test.py

import pytest

class Testonething:

    @pytest.fixture(scope="function", autouse=True)
    def setup(self, print_one):
        print("setting up")

    def test_one_thing(self):
        print("B")
        assert True

由于您的 _wrapper 是一个函数范围的自动装置:它将在同一范围内的其他装置之前被实例化。因此,热修复是在没有 autouse=True 的情况下定义 _wrapper 并尝试隐式调用该装饰器,如:

def test_abc(_wrapper):
    assert 1==0

Autouse source

[更新] 如果你没有能力改变你的测试套件,我建议你只擦除所有​​本地特定的 _wrapper 并重构你的 conftest-specified fixture 以调用 _wrapper,因为夹具功能可以自己使用其他夹具。您的 conftest.py 将如下所示:

# conftest.py
@pytest.fixture(scope="function", autouse=True)
def _wrapper(pause_on_assert):
    print("pre condition")
    yield
    print("post condition")

@pytest.fixture()
def pause_on_assert():
    yield
    if hasattr(sys, 'last_value') and isinstance(sys.last_value, AssertionError):
        tkinter.messagebox.showinfo(sys.last_value)

Modularity source

如果您想确保一段代码在测试函数之后运行,但在所有固定装置拆卸之前,我建议改用 pytest_runtest_teardown 挂钩。将 conftest.py 中的 pause_on_assert 夹具替换为:

def pytest_runtest_teardown(item, nextitem):
    if hasattr(sys, 'last_value') and isinstance(sys.last_value, AssertionError):
        tkinter.messagebox.showinfo(sys.last_value)