2011-10-27 5 views
1

はのは、私は、以下の機能を持っているとしましょう:unittestsにのみPythonコードを有効にしますか?

def f(): 
    if TESTING: 
     # Run expensive sanity check code 
    ... 

私たちはユニットテストを実行している場合にのみ、テストコードのブロックを実行するための正しい方法は何ですか?

[編集:?私はユニットテストがオンになっているかどうかを調べるためにアクセスすることができますいくつかの「グローバル」変数がある]は

+3

高価なサニティチェックコードを単体テストに直接入れることはできませんか? –

+0

unittestがいくつかの共通コードを呼び出し、その共通コードが高価なコードパスをチェックしているためです。また、中間の値をシャッフルすると同じ出力を生成する関数がありますが、実動コードの中間値をシャッフルしたくありません。 –

+3

実行したくないコードをモック/パッチアウトできるように、関数を再因子化する必要があります。 – agf

答えて

8

一般的に、私はこれをやっていないことをお勧めしたいです。あなたの生産コードは、本当に単体テストが存在することを認識すべきではありません。これの1つの理由は、あなたのif TESTINGブロックにテストをパスする(偶然にも)コードを持つ可能性があり、コードの実動でこれらのビットが実行されないため、テストでもパス。

あなたがこれを行うと主張すれば、私は考えることができる2つの可能な方法があります。

最初に、テストケースで設定したモジュールレベルTESTING varをTrueにすることができます。たとえば:

量産コード:

TESTING = False # This is false until overridden in tests 

def foo(): 
    if TESTING: 
     print "expensive stuff..." 

ユニットテストコード:

import production 

def test_foo(): 
    production.TESTING = True 
    production.foo() # Prints "expensive stuff..." 

第二の方法は、Pythonの組み込みassertキーワードを使用することです。 Pythonが-Oで実行されると、インタプリタはコード内のすべてのアサート文を削除(または無視)し、これらの高価な宝石を一貫して振りかけることができ、最適化モードで実行されると実行されないことを認識します。 -Oフラグを付けずにテストを実行してください。

例(量産コード):

def expensive_checks(): 
    print "expensive stuff..." 
    return True 

def foo(): 
    print "normal, speedy stuff." 
    assert expensive_checks() 

foo() 

出力(python mycode.pyで実行)

normal, speedy stuff. 
expensive stuff... 

出力(python -O mycode.pyで実行)

normal, speedy stuff. 

assert文について注意してください... assert文が真の値に評価されない場合、AssertionErrorが発生します。

+0

+1しかし本当にそれをしないでください。テストリグから呼び出される 'foo.expensive_test_to_ensure_some_invariant()'をコールする環境に応じて変わるコードを持つよりも良いでしょう。彼らが言うように、暗黙的より明白です。 – msw

+1

@msw私は同意します。私は私の答えを通して十分な警告を振ったと思う。必要に応じてさらに追加することができます。 –

+0

私は本当にあなたの豊富な警告に増幅を追加していました。私が嫌な経験をしているのは、たとえ偽であっても、必ず "しなければならない"と答えることができるということです。 – msw

関連する問題