2011-10-27 16 views
1

比方說,我有以下功能:只爲unittests啓用Python代碼?

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

什麼是運行只有當我們運行的是單元測試的測試代碼塊的正確方法是什麼?

[編輯:是否有一些「全局」變量我可以訪問,以找出是否單元測試都在]

+3

難道你不能直接在你的單元測試中直接使用昂貴的健康檢查代碼嗎? –

+0

否,因爲unittest會調用一些通用代碼,並且該通用代碼有我想要檢查的代碼路徑。另外,我想要檢查的函數產生相同的輸出,如果我洗牌中間值,但我不想在生產代碼中洗牌中間值。 –

+3

您需要對函數進行重新分解,以便可以模擬/修補不想運行的代碼。 – agf

回答

8

一般情況下,我建議不這樣做。你的生產代碼真的不應該意識到單元測試的存在。造成這種情況的一個原因是,您的if TESTING區塊中可能有代碼(意外)使測試通過,並且由於代碼的生產運行不會運行這些位,因此即使在您的測試中也可能會導致生產失敗通過。

但是,如果你堅持這樣做,有兩種可能的方法(我可以想到)這可以做到。

首先,您可以將您在測試用例中設置的模塊級別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一起運行時,解釋器將剝離(或忽略)代碼中的所有斷言語句,允許您將這些昂貴的gem散佈在整個表面,並知道如果以優化模式執行它們,它們將不會運行。只要確保在沒有-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