Pytest の mocker, freezer サンプル集

スクリプト
スポンサーリンク

Pytest で mockerfreezer 使うサンプルを紹介します.

スポンサーリンク

はじめに

ここ最近 Pytest でテストコードをずっと書いていたのですが,自分の用途で参考になるようなコードがなかなか無かったので,自分なりにまとめてみました.

コード全体は下記に置いてあります.

GitHub - kimata/pytest-test: pytest のテスト
pytest のテスト. Contribute to kimata/pytest-test development by creating an account on GitHub.

関数の返値の置き換え

テスト対象

テスト対象として使用するのは,以下の a.pyb.py.値を返すだけのシンプル関数です.

固定値で置き換え

常に特定の値を返すように関数を置き換えます.

呼び出しの度に変化させる

呼び出しの度に異なる値を返すように関数を置き換えます.side_effect で指定した配列サイズ以上の回数呼び出すとエラーになってしまいますので,使いどころは限られるかもしれません.

呼び出し回数で変化させる

前の例は,関数の呼び出し回数が有限でしたが,side_effectの引数を関数にすると,柔軟に返値を変えられるようになります.関数は引数を受け取れるので,引数に応じて値を変えることも簡単にできます.

特定の関数から呼び出されたときのみ変化させる

テストのカバレッジを確保する際に結構役立つのがこちらの方法.

例外を投げる

値を返すのではなく,例外を投げる場合は side_effect に例外を指定します.

注意点

from x import y という形で import された関数を置き換える場合は注意が必要です.以下のように, import した後の関数を指定して置き換える必要があります.

インスタンスの置き換え

テスト対象

テスト対象として使用するのは以下の c.py.プロパティとメソッドを各1個持つシンプルなクラスです.

メソッドとプロパティの置き換え

メソッドとプロパティでやり方が違うので注意.

時刻の置き換え

時刻を操ってテストする方法を紹介します.

テスト対象

テスト対象として使用するのは,schedule モジュールを使って Cron のように指定時刻にジョブを実行するコード.

scheduler で 1分後にジョブを実行するようにスケジューリングし,1分後に実行されたことをチェックしています.

テストの実行に1分かかってしまっているので,これを FreezeGun を使って時刻を操作することで短縮します.

時刻の操作

時刻を 12:00 にセットしたところで,スケジューリングを行い,その直後に時刻を 12:01 に進めてジョブが実行されたことを確認しています.

time.sleep(0.2)scheduleモジュールや schedule_worker スレッドが処理を進めるのを待つためのウェイトです.

注意点

multiprocessing.Queue を使っているコードで FreezeGun を使うと,Queue 操作の際に以下のようなエラーが発生することがあります.

そのため,Queue 操作の際には OverflowError をキャッチするようにしておく必要があります.

応用編

特定のユースケースでの記述例について紹介します.

open の置き換え

特定のファイルの時のみ,MagicMock を返すように組み込み関数の open を置き換えます.

このサンプルではやっていませんが,MagickMock に対して追加設定を行うことで任意のデータを読み出せる架空のファイルとかが作れるようになります.

open の置き換え (context manager 使用)

with open(): に対応する場合は以下のようにします.

requests.get の置き換え

requests には,レスポンスデータのモデルを生成できる requests.models.Response() という関数があるので,これを利用するのがオススメです.

環境変数の設定

autouse=Truefixture を使うことで,全てのテストの前に処理を走らせることができます.これを利用すると,全てのテストの実行時に環境変数をセットすることができます.

Slack 通知の無効化

先ほどと同じ仕組みを利用し,次のようにするとテスト実行時における Slack 通知を無効化できます.

コメント