2014-04-15 72 views
0

比方說,我有一個簡單的Python程序和一個簡單的測試文件Python的單元測試呼叫,並意外的程序運行

iseven.py:

import math 

def is_even(n): 
    return n%2==0 

print is_even(2) 
print is_even(3) 

和test_iseven.py:

import unittest 
from iseven import is_even 

class IsevenTests(unittest.TestCase): 
    def test1(self): 
     self.assertTrue(is_even(2)) 
     self.assertFalse(is_even(3)) 

if __name__ == '__main__': 
    unittest.main() 

在運行測試之間有差異

python test_iseven.py 

python -m unittest test_iseven.py 

?因爲我已經在指南和教程中看到過,並且輸出是相同的。另外:測試只是針對這一個功能,但是當運行測試時執行整個程序,所以我在控制檯中得到程序的輸出。這不應該發生,對吧?

回答

1

...是否有區別?

在執行測試時沒有太大的區別。

的主要區別是,在後一種情況下,你可以省略

if __name__ == '__main__': 
    unittest.main() 

,但你必須要運行測試,每次更鍵入命令行上。

所以我更喜歡第一個解決方案。

Python執行整個程序。

該行爲是正確的。爲了能夠從模塊iseven導入is_even,Python必須解析整個模塊。它不能只看功能。

由於Python是一種腳本語言,解析模塊意味着它必須執行其中的所有命令。從Python的角度來看,def是一個類似於print的命令,它創建一個新的函數實例並將其添加到當前作用域。

或者換句話說:如果它不運行print,它也不能運行def

這種行爲通常用來做魔術。例如,在爲Python我的國際化模塊,我用:

@i18n 
def name(): pass 

在運行時,我收集飾@i18n的所有功能,並把它們變成它檢查當前的語言代碼,加載從翻譯文件正確的文本和返回它。這意味着我可以在以後做:

print name() 

它會做正確的事情。

編輯現在,您可能只有在模塊作爲「程序」運行時纔會執行模塊中的代碼(即不是從其他位置導入時)。下面是你如何做到這一點:

def is_even(n): 
    return n%2==0 

def main(): 
    print is_even(2) 
    print is_even(3) 

if __name__ == '__main__': 
    main() 

一般配方:總是將所有代碼移入功能;避免將任何東西保留在模塊的「根」級別。

+0

好吧,謝謝你的出色答案。第二部分仍然很煩人,因爲它顯示了現有的打印,並且如果主程序進行了一些數字處理,那麼對於簡單的單元測試就意味着運行時間很長。此外,這從來沒有在視頻中提及:x – Basti

+1

我編輯我的答案與解決方案。 –