標籤:python 測試
16.1先測試 後編碼
16.1.1 精確的需求說明
16.1.2 為改變而計劃
覆蓋度是測試知識中重要的部分。,優秀的測試程式組的目標之一是擁有良好的覆蓋度,實現這個目標的方法之一是使用覆蓋度工具
16.2測試載入器
其中有兩個很棒的模組可以協助你自動完成測試過程:
1.unitest:通用測試架構
2.doctest:簡單一些的模組,是檢查文檔用的,但是對於編寫單元測試也很在行。
16.2.1 doctest
例如 假設求數字平方的函數,並且在文檔字串中添加了一個例子
def square(x):
Squares a number and returns the result.
>>>square(2)
4
>>>square(3)
9
...
return x*x
文檔字串中也包括了一些文本。這和測試又有什麼關係?假設square函數定義在my_math模組中。
if __name__==‘__main__‘:
import doctest,my_math
doctest.testmod(my_math)
可以只匯入doctest和my_math模組本身,然後運行doctest中的testmod函數。
$python my_math_.py
16.2.2 unitest
使用unittest架構的簡單測試
import unittest,my_math
class ProductTestCase(unittest.TestCase):
def testIntegers(self):
for x in xrange(-10,10):
for y in xrange(-10,10):
p = my_math.product(x,y)
self.failUnless(p == x*y,‘Integer multiplication failed‘)
def testFloats(self):
for x in xrange(-10,10):
for y in xrange(-10,10):
x = x/10.0
y = y/10.0
p = my_math.product(x,y)
self.failUnless(p == x*y,‘Float multiplication failed‘)
if __name__ == ‘__main__‘:unittest.main()
unittest.main函數負責運行測試。它會執行個體化所有TestCase子類,運行所有名字以test開頭的方法。
如果定義了叫做setUP和tearDown的方法,它們就會在運行每個測試方法之前和之後執行,這樣就可以用這些方法為所有測試提供一般的初始化和清理代碼,這被稱為測試夾具。
unittest模組會區分由異常引發的錯誤和調用failUnless等函數而導致的失敗。下一步就是編寫概要代碼,這樣一來就沒錯誤---只有失敗。這就意味著要建立一個包含下列內容的模組my_math。
def product(x,y):
pass
下一步讓測試代碼工作
def product(x,y):
return x * y
接下來修改product函數,讓它針對特定的數值7和9失敗。
def product(x,y):
if x==7 and y==9:
return ‘An insidious bug has surfaced!‘
else:
return x * y
16.3.1 使用PyChecker和PyLint檢查原始碼
pychecker file.py
pylint module
PyChecker和PyLint都可以作為模組匯入,但是兩者並不是真正為程式設計的。當匯入pychecker.checker時,它會檢查之後的代碼,並且在標準輸出中列印警告。pylint.lint模組有個叫做Run的非文檔記錄型函數,可以在pylint指令碼本身中使用。
使用subprocess模組調用外部檢查模組
import unittest,my_math
from subprocess import Popen,PIPE
class ProductTestCase(unittest.TestCase):
def testWithPyCheck(self):
cmd = ‘pychecker‘,‘-Q‘,my_math.__file__.rstrip(‘c‘)
pychecker = Popen(cmd,stdout=PIPE,stderr=PIPE)
self.assertEqual(pychecker.stdout.read(),‘‘)
def testWithPyLint(self):
cmd = ‘pylint‘,‘-rm‘,‘my_math‘
pylint = Popen(cmd,stdout=PIPE,stderr=PIPE)
self.assertEqual(pylint.stdout.read(),‘‘)
if __name__ == ‘__main__‘:unittest.main()
上面已經給出了檢查程式的幾個命令列開關,以避免無關的輸出幹擾測試:對於pychecker來說,提供了-Q選項,而對於pylint,我提供了-rn(n意為no)關閉報告,也就是說只顯示警告和錯誤。這裡使用了assertEqual函數以便使從stdout特性讀取的真正輸出顯示在unittest的失敗資訊中。
pylint命令會直接同給定名稱的模組一起運行,所以簡單多了。為了能讓pycheck工作正常,我們還能擷取一個檔案名稱。使用my_math模組的__file__屬性擷取這個值,用rstrip剔除任何檔案名稱末尾中可能出現的字元c。
為了能讓PyLint不出現錯誤,我忽略重寫了my_math模組。
"""
A simple math module
"""
__revision__ = ‘0.1‘
def product(factor1,factor2):
‘The product of two numbers‘
return factor1 * factor2
16.3.2 分析
標準庫中已經包含了一個叫做profile的分析模組。流量分析程式非常簡單,是要使用字串參數調用它的run方法就行了
>>>import profile
>>>from my_math import product
>>>profile.run(‘product(1,2)‘)
如果提供了檔案名稱,比如‘my_math.profile‘作為第二個參數來運行,那麼結果就會儲存到檔案中。可以在之後使用pstats模組檢查分析結果:
>>>import pstats
>>>p = pstats.Stats(‘my_math.profile‘)
本文出自 “linux_oracle” 部落格,請務必保留此出處http://pankuo.blog.51cto.com/8651697/1661450
python之測試