web-dev-qa-db-ja.com

特定のpytestマークで自動使用フィクスチャを無効にする

特定のマークでのみautouse=Trueを使用して「関数スコープ」フィクスチャの実行を防ぐことは可能ですか?

次のフィクスチャを自動使用に設定して、すべての送信リクエストが自動的にモックアウトされるようにしました。

@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

これは可能ですか?

17
Mattew Whitt

フィクスチャで 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
30
The Compiler

autouse=Trueで器具を無効にする方法を見つけることができませんでしたが、no_requests器具で行った変更を元に戻す方法を見つけました。 monkeypatch には、スタックで作成されたすべてのパッチを元に戻すメソッドundoがあるため、エンドツーエンドのテストで次のように呼び出すことができました。

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

自動使用をキャンセルまたは変更することは困難であり、おそらく不可能です

auto useのように、autouseをキャンセルすることはできません。マークの状態に基づいて、自動使用フィクスチャを変更するために何かを行うことができるかもしれません。しかし、これはハック的で難しいでしょう。

おそらく:

_import pytest
from _pytest.mark import MarkInfo
_

これを行う方法を見つけることができませんでしたが、おそらく@pytest.fixture(autouse=True)がMarkInfoを取得でき、それが「endtoend」に戻った場合、フィクスチャは属性を設定しませんでした。ただし、フィクスチャパラメータで条件を設定する必要もあります。

つまり:@pytest.fixture(True=MarkInfo, autouse=True)。そんな感じ。しかし、私は方法を見つけることができませんでした。


これを防ぐためにテストを整理することをお勧めします

次のいずれかの方法で、no_requestsをエンドツーエンドテストから分離できます。

  1. 自動使用フィクスチャの範囲を制限する
  2. no_requestsをクラスに入れます
  3. 自動使用ではなく、必要な各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()が最も簡単です。

0
Comradsky