天天看點

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):

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

下一步讓測試代碼工作

return x * y

接下來修改product函數,讓它針對特定的數值7和9失敗。

if x==7 and y==9:

return 'An insidious bug has surfaced!'

else:

16.3.1 使用PyChecker和PyLint檢查源代碼

pychecker file.py

pylint module

PyChecker和PyLint都可以作為子產品導入,但是兩者并不是真正為程式設計的。當導入pychecker.checker時,它會檢查之後的代碼,并且在标準輸出中列印警告。pylint.lint子產品有個叫做Run的非文檔記錄型函數,可以在pylint腳本本身中使用。

使用subprocess子產品調用外部檢查子產品

from subprocess import Popen,PIPE

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(),'')

上面已經給出了檢查程式的幾個指令行開關,以避免無關的輸出幹擾測試:對于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')

      本文轉自潘闊 51CTO部落格,原文連結:http://blog.51cto.com/pankuo/1661450,如需轉載請自行聯系原作者