python 單元測試 文件測試

2021-07-09 13:55:04 字數 4781 閱讀 5733

以測試為驅動的開發模式最大的好處就是確保乙個程式模組的行為符合我們設計的測試用例。在將來修改的時候,可以極大程度地保證該模組行為仍然是正確的。

栗子:mydict.py

# mydict.py

class

dict

(dict):

def__init__

(self,**kw):

super().__init__(**kw)

def__getattr__

(self,key):

try:

return self[key]

except keyerror:

raise attributeerror(r"'dict' object has no attribute '%s'" %key)

def__setattr__

(self,key,value):

self[key] = value

my_dict_test.py

# my_dict_test.py

import unittest

# 從mydict.py檔案引入 dict類

from mydict import dict

class

testdict

(unittest.testcase):

deftest_init

(self):

d = dict(a=1,b='test')

self.assertequal(d.a,1) # assertequal 斷言函式返回的結果與1相等

self.assertequal(d.b,'test')

self.asserttrue(isinstance(d,dict))

deftest_key

(self):

d = dict()

d['key'] = 'value'

self.assertequal(d.key,'value')

deftest_attr

(self):

d = dict()

d.key = 'value'

self.asserttrue('key'

in d)

self.assertequal(d['key'],'value')

deftest_keyerror

(self):

d = dict()

with self.assertraises(keyerror): # 該斷言 期待丟擲指定型別的error,比如通過d['empty']訪問不存在的key時,斷言會丟擲keyerror

value = d['empty']

deftest_attrerror

(self):

d = dict()

with self.assertraises(attributeerror): # 而通過d.empty訪問不存在的key時,我們期待丟擲attributeerror

value = d.empty

# 執行測試方法一

#if __name__ == '__main__':

#unittest.main()

執行測試方法一:在mydict_test.py的最後加上兩行**:

if __name__ == '__main__':

unittest.main()

這樣就可以把mydict_test.py當做正常的python指令碼執行:

方法二:

在命令列通過引數-m unittest直接執行單元測試:

這是推薦的做法,因為這樣可以一次批量執行很多單元測試,並且,有很多任務具可以自動來執行這些單元測試。

可以在單元測試中編寫兩個特殊的setup()和teardown()方法。這兩個方法會分別在每呼叫乙個測試方法的前後分別被執行。

setup()和teardown()方法有什麼用呢?設想你的測試需要啟動乙個資料庫,這時,就可以在setup()方法中連線資料庫,在teardown()方法中關閉資料庫,這樣,不必在每個測試方法中重複相同的**:

class

testdict

(unittest.testcase):

defsetup

(self):

print('setup...')

defteardown

(self):

print('teardown...')

...

可以再次執行測試看看每個測試方法呼叫前後是否會列印出setup…和teardown

小結

單元測試可以有效地測試某個程式模組的行為,是未來重構**的信心保證。

單元測試的測試用例要覆蓋常用的輸入組合、邊界條件和異常。

單元測試**要非常簡單,如果測試**太複雜,那麼測試**本身就可能有bug。

單元測試通過了並不意味著程式就沒有bug了,但是不通過程式肯定有bug。

>>> 

import re

>>> m = re.search('(?<=abc)def', 'abcdef')

>>> m.group(0)

'def'

可以把這些示例**在python的互動式環境下輸入並執行,結果與文件中的示例**顯示的一致。

這些**與其他說明可以寫在注釋中,然後,由一些工具來自動生成文件。既然這些**本身就可以貼上出來直接執行,那麼,可不可以自動執行寫在注釋中的這些**呢?

答案是肯定的。

當我們編寫注釋時,如果寫上這樣的注釋:

def

abs(n):

''' function to get absolute value of number.

example:

>>> abs(1)

1>>> abs(-1)

1>>> abs(0)

0'''

return n if n >= 0

else (-n)

無疑更明確地告訴函式的呼叫者該函式的期望輸入和輸出。

並且,python內建的「文件測試」(doctest)模組可以直接提取注釋中的**並執行測試。

doctest嚴格按照python互動式命令列的輸入和輸出來判斷測試結果是否正確。只有測試異常的時候,可以用…表示中間一大段煩人的輸出。

讓我們用doctest來測試上次編寫的dict類:

# mydict2.py

class

dict

(dict):

''' ****** dict but also support access as x.y style.

>>> d1 = dict()

>>> d1['x'] = 100

>>> d1.x

100>>> d1.y = 200

>>> d1['y']

200>>> d2 = dict(a=1, b=2, c='3')

>>> d2.c

'3'>>> d2['empty']

traceback (most recent call last):

...keyerror: 'empty'

>>> d2.empty

traceback (most recent call last):

...attributeerror: 'dict' object has no attribute 'empty'

'''def__init__

(self, **kw):

super(dict, self).__init__(**kw)

def__getattr__

(self, key):

try:

return self[key]

except keyerror:

raise attributeerror(r"'dict' object has no attribute '%s'" % key)

def__setattr__

(self, key, value):

self[key] = value

if __name__=='__main__':

import doctest

doctest.testmod()

什麼輸出也沒有。這說明我們編寫的doctest執行都是正確的。如果程式有問題,比如把getattr()方法注釋掉,再執行就會報錯:

注意到最後3行**。當模組正常匯入時,doctest不會被執行。只有在命令列直接執行時,才執行doctest。所以,不必擔心doctest會在非測試環境下執行。

Python 單元測試

一 假設我們編寫了一段程式,主要功能是完成阿拉伯數字和羅馬數字之間的轉換 在羅馬數字中,利用7個字母進行重複或者組合來表達各式各樣的數字 i 1 v 5 x 10 l 50 c 100 d 500 m 1000 還有一些關於構造羅馬數字的規則。此程式的框架如下 其中,class romanerror...

python 單元測試

assertequal a,b assertnotequal a,b 斷言值是否相等 assertis a,b assertisnot a,b 斷言是否同一物件 記憶體位址一樣 assertlistequal list1,list2 assertitemnotequal list1,list2 斷言...

Python單元測試

本文章整理自 使用python3.6編寫乙個單元測試demo,例如 對學生student類編寫乙個簡單的單元測試。1 編寫student類 usr bin env python3 coding utf 8 class student object def init self,name,score s...