禁用特定pytest标记上的autouse灯具

Mat*_*itt 14 python pytest pytest-django

是否可以autouse=True仅使用特定标记来阻止"功能范围"灯具的执行?

我将以下fixture设置为autouse,以便自动模拟所有传出请求:

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

但我有一个标记叫做endtoend我用来定义一系列测试,允许外部请求进行更强大的端到端测试.我想注入no_requests所有测试(绝大多数),但不是在以下测试中:

@pytest.mark.endtoend
def test_api_returns_ok():
    assert make_request().status_code == 200
Run Code Online (Sandbox Code Playgroud)

这可能吗?

The*_*ler 26

您还可以使用夹具中的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
Run Code Online (Sandbox Code Playgroud)

输出-vs:

x.py::test1 patching stuff
PASSED
x.py::test2 PASSED
Run Code Online (Sandbox Code Playgroud)

  • @Anentropic 确实 - 请注意,在大多数情况下,如果有多个标记,您对获取所有标记不感兴趣,因此 `request.node.get_closest_marker("name")` 可能会让事情变得更容易。 (3认同)
  • 很有用!作为附录... `request.keywords["noautofixit"]` 仅在标记存在时返回 bool `True`。如果您的标记有 args,最好使用 `request.node.iter_markers("noautofixit")`,然后您就可以访问具有可用的 `name`、`args` 和 `kwargs` 的 `Mark` 对象。 (2认同)

Jar*_*rno 9

如果您endtoend在特定模块或类中有您的测试,您也可以no_requests本地覆盖该装置,例如假设您将所有集成测试分组在一个名为 的文件中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

Run Code Online (Sandbox Code Playgroud)


Mat*_*itt 8

我无法找到一种方法来禁用固定装置autouse=True,但我确实找到了一种方法来恢复在固定装置中所做的更改no_requestsmonkeypatch有一个方法undo可以恢复在堆栈上制作的所有补丁,因此我可以在端到端测试中调用它,如下所示:

@pytest.mark.endtoend
def test_api_returns_ok(monkeypatch):
    monkeypatch.undo()
    assert make_request().status_code == 200
Run Code Online (Sandbox Code Playgroud)