python 禁用特定pytest标记上的自动使用装置

jtw3ybtb  于 2023-05-05  发布在  Python
关注(0)|答案(5)|浏览(115)

是否有可能只在特定标记上使用autouse=True来阻止“功能范围”的fixture的执行?
我将以下fixture设置为autouse,以便自动模拟所有传出的请求:

@pytest.fixture(autouse=True)
def no_requests(monkeypatch):
    monkeypatch.setattr("requests.sessions.Session.request", MagicMock())

但是我有一个名为endtoend的标记,我用它来定义一系列测试,这些测试允许发出外部请求,以进行更健壮的端到端测试。我想在所有测试中注入no_requests(绝大多数),但不是在以下测试中:

@pytest.mark.endtoend
def test_api_returns_ok():
    assert make_request().status_code == 200

这可能吗?

epggiuax

epggiuax1#

您还可以使用fixture中的request对象来检查测试中使用的标记,如果设置了特定的标记,则不执行任何操作:

import pytest

@pytest.fixture(autouse=True)
def autofixt(request):
    if 'noautofixt' in request.keywords:
        return
    print("patching stuff")

def test1():
    pass

@pytest.mark.noautofixt
def test2():
    pass

-vs输出:

x.py::test1 patching stuff
PASSED
x.py::test2 PASSED
aydmsdu9

aydmsdu92#

如果您在特定的模块或类中有endtoend测试,您也可以在本地覆盖no_requests fixture,例如假设您将所有集成测试分组在一个名为end_to_end.py的文件中:

# test_end_to_end.py

@pytest.fixture(autouse=True)
def no_requests():
    return

def test_api_returns_ok():
    # Should make a real request.
    assert make_request().status_code == 200
lg40wkob

lg40wkob3#

我无法找到禁用autouse=True fixture的方法,但我找到了恢复no_requests fixture中所做更改的方法。monkeypatch有一个方法undo,它可以恢复堆栈上的所有补丁,所以我可以在端到端测试中调用它,如下所示:

@pytest.mark.endtoend
def test_api_returns_ok(monkeypatch):
    monkeypatch.undo()
    assert make_request().status_code == 200
zkure5ic

zkure5ic4#

取消或更改autouse很困难,可能不可能

你不能取消汽车,因为它是自动驾驶的。也许你可以做些什么来改变自动夹具的基础上马克的条件。但这将是黑客和困难。
可能有:

import pytest
from _pytest.mark import MarkInfo

我找不到一种方法来做到这一点,但也许@pytest.fixture(autouse=True)可以获得MarkInfo,如果它返回“端到端”,则fixture不会设置该属性。但是您还必须在fixture参数中设置一个条件。
即:@pytest.fixture(True=MarkInfo, autouse=True)。差不多吧但我找不到办法。

建议您组织测试以防止此情况发生

您可以通过以下方式将no_requests与端到端测试分开:
1.限制你的自动装置的范围
1.将no_requests放入类中
1.不要让它自动使用,只要把它传递到你需要的每个def的参数中就可以了
就像这样:

class NoRequests:
    @pytest.fixture(scope='module', autouse=True)
    def no_requests(monkeypatch):
        monkeypatch.setattr("requests.sessions.Session.request", MagicMock())
    def test_no_request1(self):
        # do stuff here
    # and so on

这是很好的练习。也许另一个组织能帮上忙

但在您的情况下,monkeypatch.undo()可能是最简单的

oo7oh9g9

oo7oh9g95#

只需更新副作用以使用实际功能。

import pytest
from unittest import mock

from my_module import my_func

@pytest.fixture(autouse=True)
def auto_use_mock():
    with mock.patch("my_module.my_func") as mocked_func:
        yield mocked_func

def test_skipping_autouse(auto_use_mock):
    # update the side effect to point at the thing you mocked
    auto_use_mock.side_effect = my_func
    
    ...rest of your test

相关问题