目次

前のトピックへ

標準出力/標準エラーのキャプチャ

次のトピックへ

xdist: pytest の分散テストプラグイン

モンキーパッチ/モックのモジュールと環境

時々、グローバル設定に依存する機能のテストを実行する、またはネットワークアクセスを伴うような簡単にテストできないコードを実行する必要があります。 monkeypatch という関数の引数を使うことで、属性、ディクショナリの項目、環境変数、インポートのための sys.path の変更を安全に追加/削除するのを支援します。入門記事とその動機付けの議論は monkeypatch のブログ記事 を参照してください。

簡単な例: モンキーパッチ機能

os.expanduser が特定のディレクトリを返すようにさせたい場合、関数内で os.expanduser が呼ばれる前にこの関数へパッチを当てるために monkeypatch.setattr() メソッドが使えます:

# test_module.py の内容
import os.path
def getssh(): # 疑似アプリケーションコード
    return os.path.join(os.path.expanduser("~admin"), '.ssh')

def test_mytest(monkeypatch):
    def mockreturn(path):
        return '/abc'
    monkeypatch.setattr(os.path, 'expanduser', mockreturn)
    x = getssh()
    assert x == '/abc/.ssh'

このテスト関数は os.path.expanduser にモンキーパッチを当てた後で、ある関数内からその関数が呼ばれます。このテスト関数が終了した後で os.path.expanduser に対する変更は元に戻ります。

関数の引数 monkeypatch のメソッドリファレンス

class _pytest.monkeypatch.monkeypatch[ソース]

object keeping a record of setattr/item/env/syspath changes.

chdir(path)[ソース]

change the current working directory to the specified path path can be a string or a py.path.local object

delattr(obj, name, raising=True)[ソース]

delete attribute name from obj, by default raise AttributeError it the attribute did not previously exist.

delenv(name, raising=True)[ソース]

delete name from environment, raise KeyError it not exists.

delitem(dic, name, raising=True)[ソース]

delete name from dict, raise KeyError if it doesn’t exist.

setattr(obj, name, value, raising=True)[ソース]

set attribute name on obj to value, by default raise AttributeEror if the attribute did not exist.

setenv(name, value, prepend=None)[ソース]

set environment variable name to value. if prepend is a character, read the current environment variable value and prepend the value adjoined with the prepend character.

setitem(dic, name, value)[ソース]

set dictionary entry name to value.

syspath_prepend(path)[ソース]

prepend path to sys.path list of import locations.

undo()[ソース]

undo previous changes. This call consumes the undo stack. Calling it a second time has no effect unless you do more monkeypatching after the undo call.

monkeypatch.setattr/delattr/delitem/delenv() の全ての関数において、変更対象が存在しない場合にデフォルトで例外を発生させます。このチェック処理をスキップしたいなら raising=False を渡してください。