⛰️

Pytest で requests の Retry・Timeout設定 のテストしたい

2022/09/15に公開

Pytestのまとめは こちら を参照ください。

はじめに

HTTPクライアントとしてよく利用される requests ではリトライ・タイムアウトの設定が当然あります。通常のロジック開発においては、あまりそういうケースはないのでしょうが、たまにリトライやタイムアウトの設定をUnitTestでテストしたいと思うことがありました。

requests 自体を requests_mock などでMock化することはよくあるかもしれませんが、それではテストが行えません。こんなことはHTTPClientを実装するとき以外発生しないのかもしれませんが、メモとして残します。

pytest-httpserver

https://pytest-httpserver.readthedocs.io/en/latest/

こちらを利用します。
このライブラリは、pytest実行中にWebServerを建てることができるものです。
また、レスポンスの返却処理をCallback関数で指定することができるため、Sleepを入れたり呼び出された回数によって返却値を変化させたりということが可能になります。

実装例(基本パターン)

Pytest中に localhost:8000 でHTTPServerを立ち上げる。

conftest.py

@pytest.fixture(scope='session')
def httpserver_listen_address():
  return "localhost", 8000

testcase.py

from pytest_httpserver import HTTPServer
from werkzeug import Response

def request_handler(request: Request) -> Response:
  return Response('{\"body\": \"text\"}', status=200)

@pytest.mark.userfixture('httpserver_listen_address')
def test_some_target(httpserver: HTTPServer) -> None:
  httpserver.clear()
  httpserver.expect_request('/path/to/the/request')
    .response_with_handler(request_handler)
  
  # 便宜上書いてますが、普通はテスト対象からアクセス
  response = requests.get('http://localhost:8000/path/to/the/request')
  # omitted...

もしタイムアウトの試験をしたいのであれば、 request_handlertime.sleep(n) を入れるなどで対応が可能となる。

Discussion