2017-09-15 20 views
1

私は複数のos.system呼び出しを行うPythonスクリプトを持っています。一連の文字列を文字列のリストとしてアサートするのは簡単です(そして比較的エレガントです)。単体テストのためのos.systemを模擬する最善の方法(PyTest)

実際の呼び出しをインターセプト(およびブロック)するのは簡単ではありません。問題のスクリプトでは、私はできたので、のようなSUT(*)で抽象os.systemは:

os_system = None 

def main(): 
    return do_the_thing(os.system) 

def do_the_thing(os_sys): 
    global os_system 
    os_system = os_sys 

    # all other function should use os_system instead of os.system 

私のテストは、my_script.do_the_thing()の代わりに、当然のmy_script.main()(未テストコードの小さな量を残す)を呼び出します。

代替オプション:私はそのままSUTを残し、SUTにmain()を起動する前に試験方法でグローバルos.systemを置き換えることができます。

これは、それがグローバルかつ永続的な変化であるという点で私に新しい問題を残す。ファインなので、同じテスト方法でtry/finallyを使用し、テスト方法を終了する前に元のものと置き換えます。それはテストメソッドが合格したか失敗したかにかかわらず動作します。

PyTestには、のセットアップ/ティアダウン中心の方法がありますか?ですか?

その他の合併症:私はstdoutとstderrで同じことをしたいと思います。はい、実際には私がテストしているmain()スクリプトです。

  • SUT ==テスト対象システム

答えて

2

ザパイソン3(> = 3.3)標準ライブラリは、公式文書でgreat tutorial about Mockを有しています。 Python 2の場合、PyPiのバックポートライブラリMockを使用できます。

ここでは使用例を示します。

import os 


def my_function(src_dir): 
    os.system('ls ' + src_dir) 

これを行うには、あなたはこのように、unittest.mock.patchデコレータを使用することができます:

import unittest.mock 


@unittest.mock.patch('os.system') 
def test_my_function(os_system): 
    # type: (unittest.mock.Mock) -> None 
    my_function("/path/to/dir") 
    os_system.assert_called_once_with('ls /path/to/dir') 

このテスト機能は中にos.systemコールにパッチを適用しますあなたは、この機能でos.systemへの呼び出しをモックとしたいと言いますその実行。最後にos.systemが復元されます。

次に、呼び出し、パラメータ、および結果を確認するためのいくつかの「アサート」メソッドがあります。また、特定のサーカスで例外が発生していることを確認することもできます。

+0

PyTestとPython2の場合は、@ mock.patch( 'os.system')なので、作品をよく確認できます。 –

関連する問題