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

时间:2016-08-03 15:47:56

标签: python pytest pytest-django

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

我将以下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

这可能吗?

4 个答案:

答案 0 :(得分:19)

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

如果您将endtoend测试放在特定的模块或类中,则也可以只在本地override 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

答案 3 :(得分:0)

取消或更改autouse

会很困难,也可能无法取消

你不能使用autouse,因为它的自动使用。也许你可以根据商标的条件做一些改变autouse灯具的事情。但这将是黑客和困难。

可能与:

import pytest
from _pytest.mark import MarkInfo

我无法找到一种方法来做到这一点,但也许@pytest.fixture(autouse=True)可能会获得MarkInfo,如果它回来了,那么' endtoend'夹具不会设置属性。但您还必须在夹具参数中设置条件。

即:@pytest.fixture(True=MarkInfo, autouse=True)。这样的事情。但我找不到办法。

建议您组织测试以防止此

您可以通过以下任一方式将no_requests与endtoend测试分开:

  1. 限制你的autouse灯具的范围
  2. 将no_requests放入类
  3. 不要将其作为自动使用,只需将其传递到您需要的每个def的参数中
  4. 像这样:

    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()

    可能最容易