Python學習筆記 8 3章 單元測試

2021-08-28 08:19:00 字數 4756 閱讀 3431

1、概覽

單元測試是用來對乙個模組、乙個函式或者乙個類來進行正確性檢驗的測試工作。

比如對函式

abs()

,我們可以編寫出以下幾個測試用例:

輸入正數,比如1、

1.2、

0.99

,期待返回值與輸入相同;

輸入負數,比如-1、

-1.2

、-0.99

,期待返回值與輸入相反;輸入0

,期待返回0;

輸入非數值型別,比如

none、

、{},期待丟擲

typeerror

。 把上面的測試用例放到乙個測試模組裡,就是乙個完整的單元測試。

單元測試的意義:

1.1、編寫乙個測試單元

編寫乙個

dict

類,這個類的行為和

dict

一致,但是可以通過屬性來訪問。

#mydict.py

class dict(dict):

def __init__(self, **kw):

# 初始化例項,可以傳入任意個關鍵字引數,即鍵值對

super().__init__(**kw)

#super()

無引數,是按

mro表,呼叫父類的方法。這裡是將

**kw

交給父類

dict

初始化

def __getattr__(self, key):

#dict

沒有設定初始屬性,所以

dict()

每使用乙個屬性,會用到

__getattr__

方法 try:

return self[key]

# 如果有該屬性,正常執行

except keyerror:

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

# 無該屬性,丟擲錯誤

def __setattr__(self, key, value):

# 新增鍵值對。即新增屬性

self[key] = value

編寫單元測試

#mydict_test.py

import unittest

from mydict import dict

# 繼承的父類是unittest.testcase

# 它提供了很多內建的條件判斷,我們只需要呼叫這些方法就可以斷言輸出是否是我們所期望的

class testdict(unittest.testcase):

def test_init(self):

# 測試

dict

能否正常建立例項,並獲取到例項的屬性

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

self.assertequal(d.a, 1)#斷言

d.a

的返回結果與

1相等。相等才能繼續執行

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

self.asserttrue(isinstance(d, dict))

def test_key(self):

# dict()

能否正確新增屬性

d = dict()

d['key'] = 'value'

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

def test_attr(self):

# dict()

能否正確獲取屬性的

value

d = dict()

d.key = 'value'

self.asserttrue('key' in d)

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

def test_keyerror(self):

# 錯誤測試

d = dict()

with self.assertraises(keyerror):

# 獲取不存在的屬性的

value

值時,期待報錯

value = d['empty']

def test_attrerror(self):

# 錯誤測試,同上,獲取屬性

value

值得方法不同,丟擲的錯誤不同

d = dict()

with self.assertraises(attributeerror):

# 獲取不存在的屬性的

value

值時,期待報錯

value = d.empty

總結:

with self.assertraises(keyerror):

value = d['empty']

執行單元測試

執行方式一:

在mydict_test.py的最後加上兩行**,這樣可以把mydict_test.py當做正常的python指令碼執行

if __name__ == '__main__':

unittest.main()

$ python mydict_test.py

執行方式二:

在命令列通過引數-m unittest直接執行單元測試,這樣可以一次批量執行很多單元測試

$ python -m unittest mydict_test

1.2、setup

與teardown

setup()和teardown()方法。會分別在每呼叫乙個測試方法的前後分別被執行

用法: 如果你的測試需要啟動乙個資料庫,就可以在setup()方法中連線資料庫,在teardown()方法中關閉資料庫,這樣,不必在每個測試方法中重複相同的**:

class testdict(unittest.testcase):

def setup(self):

print('setup...')

def teardown(self):

print('teardown...')2、

super()

函式 我們在編寫dict類時。用到了super(),並用其呼叫了父類dict的方法。在此,我們詳解supper()。

super()

的功能就是呼叫父類函式的方法,並且保證每個父類函式只呼叫一次(如果每個類都使用super)

2.1、super()

的入門與使用

在類的繼承中,如果重定義某個方法,該方法會覆蓋父類的同名方法,但有時,我們希望能同時實現父類的功能,這時,我們可以用super()呼叫父類的方法。

class animal(object):

# 定義了乙個

animal

類 def __init__(self, name):

self.name = name

def greet(self):

# 定義了乙個

greet()

方法 print 'hello, i am %s.' % self.name

class dog(animal):

#定義了乙個

dog類,父類是

animal

def greet(self):

# 也定以了乙個

greet()

方法,但這個方法是呼叫

animal

的方法 super(dog, self).greet()   #將

dog建立的例項名,按

mro

表的順序,傳給

dog的下乙個父類,呼叫該父類的方法

print 'wangwang...'

# 呼叫結果

>>> dog = dog('dog')

>>> dog.greet()

hello, i am dog.

# 父類方法

wangwang..

# 子類方法

2.2、mro

列表 雖然

super

()呼叫父類的方法,但卻和父類沒有實質性的關聯。它的呼叫順序是根據

mro表來的

對於你定義的每乙個類,python 會計算出乙個方法解析順序(method resolution order, mro)列表,它代表了類繼承的順序

>>> dog.mro()#檢視

dog類的

mro表

[, , ]

>>> c.mro()  

# base是[a

、b]的父類,[a、

b]是c的父類

[__main__.c, __main__.a, __main__.b, __main__.base, object]

mro 列表的順序通過乙個 c3 線性化演算法來實現的。總的來說,乙個類的 mro 列表就是合併所有父類的 mro 列表,並遵循以下三條原則:

2.3、super

工作原理

super工作原理如下:

def super(cls, inst):

# cls

錶類,inst

是cls

建立的例項。獲 cls 在 inst 的 mro 列表中的下乙個類。

mro = inst.__class__.mro()

# 獲取

inst

的mro

表 return mro[mro.index(cls) + 1]

#返回表中當前

cls的下標,並

+1,即返回當前

cls的下乙個父類

python: 你不知道的 super

(

python學習筆記 day8(3)

def 函式名 引數列表 函式體return 表示式 在沒有引數時,要保留 在return時,會根據表示式返回乙個值給呼叫方,如果不帶返回值,則相當於返回 none 通過函式名呼叫函式,也要注意在呼叫函式時引數的問題。在python中,型別屬於物件,變數沒有型別 在傳入引數時,不同的引數型別會產生不...

Python學習筆記 8 3 函式 返回值

例1 def db connect ip,port 3306 print ip,port res db connect 118.24.3.40 3307 如果函式中沒有return,print res 會返回none。例2 def my2 for i in range 50 return i pri...

Python學習筆記 12 10章 XML

1 概覽 xml雖然比json複雜,在web中應用也不如以前多了,不過仍有很多地方在用,所以,有必要了解如何操作xml。1 dom vs sax 操作xml有兩種方法 dom和sax。dom會把整個xml讀入記憶體,解析為樹,因此占用記憶體大,解析慢,優點是可以任意遍歷樹的節點。sax是流模式,邊讀...