【问题标题】:How to impose order on fixtures in pytest?如何在pytest中对固定装置施加顺序?
【发布时间】:2022-02-09 19:35:55
【问题描述】:

我正在尝试使用pytest-dependency 使fixtures按顺序发生,无论它们是如何命名的,也无论它们在测试参数列表中出现的顺序如何。

我需要这个的原因是创建需要初始化的夹具,这些夹具依赖于其他需要初始化的夹具,并且它们必须按顺序发生。我有很多这样的,我不想依赖命名或参数列表中的顺序。

我也不想使用pytest_sessionstart,因为它不能接受夹具输入,这会导致代码非常不干净。


the doc 中的简单示例展示了如何为测试创建编程依赖项:

import pytest

@pytest.mark.dependency()
@pytest.mark.xfail(reason="deliberate fail")
def test_a():
    assert False

@pytest.mark.dependency()
def test_b():
    pass

@pytest.mark.dependency(depends=["test_a"])
def test_c():
    pass

@pytest.mark.dependency(depends=["test_b"])
def test_d():
    pass

@pytest.mark.dependency(depends=["test_b", "test_c"])
def test_e():
    pass

这适用于输出:

============================= test session starts =============================
collecting ... collected 5 items

test_sanity.py::test_z XFAIL (deliberate fail)                           [ 20%]
@pytest.mark.dependency()
    @pytest.mark.xfail(reason="deliberate fail")
    def test_z():
>       assert False
E       assert False

test_sanity.py:6: AssertionError

test_sanity.py::test_x PASSED                                            [ 40%]
test_sanity.py::test_c SKIPPED (test_c depends on test_z)                [ 60%]
Skipped: test_c depends on test_z

test_sanity.py::test_d PASSED                                            [ 80%]
test_sanity.py::test_w SKIPPED (test_w depends on test_c)                [100%]
Skipped: test_w depends on test_c


=================== 2 passed, 2 skipped, 1 xfailed in 0.05s ===================

现在我想对灯具做同样的事情。

我的尝试:

conftest.py:

import pytest

pytest_plugins = ["dependency"]


@pytest.mark.dependency()
@pytest.fixture(autouse=True)
def zzzshould_happen_first():
    assert False


@pytest.mark.dependency(depends=["zzzshould_happen_first"])
@pytest.fixture(autouse=True)
def should_happen_last():
    assert False

test_sanity.py:

def test_nothing():
    assert True

输出

test_sanity.py::test_nothing ERROR                                       [100%]
test setup failed
@pytest.mark.dependency(depends=["zzzshould_happen_first"])
    @pytest.fixture(autouse=True)
    def should_happen_last():
>       assert False
E       assert False

conftest.py:15: AssertionError

我预计 zzzshould_happen_first 会出现错误。


有没有办法对固定装置进行排序,例如

  1. 他们的名字被忽略了
  2. 它们在参数列表中的顺序被忽略
  3. 仍然可以应用其他 pytest 功能,例如 autouse

【问题讨论】:

    标签: python dependencies pytest pytest-dependency


    【解决方案1】:

    您可以使用 pytest 直接将一个夹具作为依赖项。像这样的:

    import pytest
    
    
    @pytest.fixture(autouse=True)
    def zzzshould_happen_first():
        assert False
    
    
    @pytest.fixture(autouse=True)
    def should_happen_last(zzzshould_happen_first):
        assert False
    
    
    def test_nothing():
        assert True
    

    它给了你想要的:

    test setup failed
    @pytest.fixture(autouse=True)
        def zzzshould_happen_first():
    >       assert False
    E       assert False
    
    answer.py:7: AssertionError
    

    【讨论】:

    • 谢谢,这确实是一个简单的解决方案!很抱歉,我现在必须添加一个我没有想到的细节:我正在使用 a plugin 添加自己的固定装置。它们需要外部初始化,但我无法更改它们。我知道这是一个完全不同的问题,但也许你有一个想法?我想强制我自己的夹具在任何其他夹具之前运行,然后我将能够使用这个建议的方法。
    • 理想情况下,您应该能够为之前调用的夹具提供一个函数。但也许您的用例不需要对插件进行任何更改。我认为你应该问一些关于你试图实现的细节的问题(主要是为什么你需要在加载 docker-compose 之前做一些事情)。
    • 在 docker-compose up 之前我需要的是... docker-compose down(以及网络删除和网络创建)。如果环境不干净,图书馆不会清理,所以我必须在它发挥作用之前这样做。
    • 在这种情况下,我认为您应该分叉初始项目(或打开一个问题)以添加您的功能。
    • 我正在尝试使用这种用法运行单个测试,但如果它依赖于另一个测试,它就不会运行,而不是首先调用该测试。这可以解决吗?我不想每次都运行整个套件
    猜你喜欢
    • 2014-10-28
    • 1970-01-01
    • 2021-02-08
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    相关资源
    最近更新 更多