2016-05-31 19 views
0

私は、3つの異なる例を考慮し、各ケースのために私が書きたいPyTest:関数がで呼び出されたテストの文

def my_fun(input): 
if input == 1: 
    fun1() 
if input == 2: 
    fun2() 
if input == 3: 
    fun3() 

以下の例のように、別の関数を呼び出す関数を持っている場合関数my_funを使用してpy.testを使用してテストしましたが、適切な関数が特定の入力に対して呼び出されたかどうかをテストする方法がわかりません。

+0

限り出力は正しいです、どの関数が呼び出されたかは本当に気になりますか? – fmarc

+0

@fmarcもちろん、3つの可能な入力をテストして出力をチェックすることができますが、これは3つの関数fun1、fun2、fun3をすべて実行しなければならないことを意味し、それを行うもっとエレガントな方法を探しています。 – Ziva

+0

fun1/2/3のテストを直接書くこともできますか? my_fun()にはほとんどコードが含まれていないため、テストを書くことはほとんどありません。 – fmarc

答えて

2

すべてのfun1()、fun2()、fun3()が結果を返したら、私はパラメータ化に行きます。

# Here an example of functions to be tested 

def fun1(): 
    return 1 
def fun2(): 
    return 2 
def fun3(): 
    return 3 

def my_fun(input): 
    if input == 1: 
     return fun1() 
    if input == 2: 
     return fun2() 
    if input == 3: 
     return fun3() 

ここで、テストマトリックス。 (あなたが質問に尋ねたよう)あなたがテストで関数呼び出しを一致させることができるように期待される結果は、テスト中も、関数の呼び出しです:

# Parametrized test 
import pytest 

@pytest.mark.parametrize("test_input, expected", [(1, fun1()), (2, fun2()), (3, fun3())]) 
# --------------------------------------- 
# test_input | 1 | 2 | 3 | 
# --------------------------------------- 
# expected | fun1() | fun2() | fun3() | 
# --------------------------------------- 
def test_my_fun(test_input, expected): 
    assert my_fun(test_input) == expected 

試運転:

mac: py.test -v test_parametrization.py 
=================================================================================== test session starts ==================================================================================== 
platform darwin -- Python 2.7.11, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python 
cachedir: .cache 
rootdir: /Users/user/Repos/playground, inifile: 
plugins: hidecaptured-0.1.2, instafail-0.3.0 
collected 3 items 

test_parametrization.py::test_my_fun[1-1] PASSED 
test_parametrization.py::test_my_fun[2-2] PASSED 
test_parametrization.py::test_my_fun[3-3] PASSED 

================================================================================= 3 passed in 0.01 seconds ================================================================================= 
-3

なぜ複数のif文で、elifではないのですか?彼らは条件が互いに排他的なので、別の小切手を捨てるのはなぜですか?しかし、いずれにせよ、どのようにのようなダミー印刷物、について:私は十分な評判を持っていた場合

def my_fun(input): 
    if input == 1: 
     fun1() 
     print("Function 1 executed ?") 
    elif input == 2: 
     fun2() 
     print("Function 2 executed ?") 
    elif input == 3: 
     fun3() 
     print("Function 3 executed ?") 

私はちょうどところでコメントします。 #JustWannaGetTo50

+0

彼は 'py.test'と言った。 –

3

@fmarcがコメントしたように、どの関数が呼び出されるかは、my_funが正しいことをテストするよりも重要ではありません。しかし、3つの関数のそれぞれを模擬し、それぞれの関数が実際に行うこととは無関係に正しい関数が呼び出されたかどうかをテストすることができます。 (mockは、インストールする必要がありますのPython 2でサードパーティのモジュールであることに注意してください。それは、Python 3.3で標準ライブラリ利用可能である()unittest.mockとして?。)

一つの簡単な例:

import mock 

def test_my_fun(): 
    with mock.patch('fun1', wraps=fun1) as mock_fun1: 
     with mock.patch('fun2', wraps=fun2) as mock_fun2: 
      with mock.patch('fun3', wraps=fun3) as mock_fun3: 
       my_fun(1) 
       mock_fun1.assert_called_with() 
       mock_fun2.assert_not_called() 
       mock_fun3.assert_not_called() 
は、

mockのインストールのドキュメントを参照して、サポートされている方法を確認してください。

+0

Py2.7以降、複数のコンテキストマネージャを1つのwith文で使用できることに注意してください。この場合非常に読みにくいですが、インデントを保存します。 – fmarc

+0

ああ、そうです。私はずっと長い間2.6で立ち往生していましたが、追加されたときは忘れました。 – chepner

+1

また、あなたが単純に行うことができるように、(IMHO)がこれを単純化する '嘲笑'のフィクスチャを与える[pytest-mock](https://github.com/pytest-dev/pytest-mock)もあります。 'mock_fun1 = mock.match( 'fun1'、wraps = fun1) 'などがあり、テストの後にフィクスチャはクリーンアップを行います。 –

関連する問題