1. 程式人生 > >在python中對一個類編寫單元測試

在python中對一個類編寫單元測試

類Dict在檔案abstest.py中

class Dict(dict):
	
	def __init__(self,**kw):
		super().__init__(**kw)

	def __getattr__(self,key):
		try:
			return self[key]
		except KeyError:
			raise AttributeError('Dict object has no attribute %s' % key)

	def __setattr__(self,key,value):
		self[key]=value

類TestDict在檔案hello.py下

import unittest

from abstest import Dict

#測試單元
class TestDict(unittest.TestCase):

	def test_init(self):
		d=Dict(a=1,b='test')
		self.assertEqual(d.a,1)
		self.assertEqual(d.b,'test')
		self.assertEqual(isinstance(d,dict),True)
	def test_key(self):
		d=Dict()
		d['key']='value'
		self.assertEqual(d['key'],'value')
	def test_attr(self):
		d=Dict()
		d.key='value'
		self.assertEqual('key' in d,True)
		self.assertEqual(d['key'],'value')
	def test_keyerror(self):
		d=Dict()
		with self.assertRaises(KeyError):
			value=d['empty']
	def test_attrerror(self):
		d=Dict()
		with self.assertRaises(AttributeError):
			value=d.empty

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

編寫單元測試時,我們需要編寫一個測試類,從unittest.TestCase繼承。

test開頭的方法就是測試方法,不以test開頭的方法不被認為是測試方法,測試的時候不會被執行。

對每一類測試都需要編寫一個test_xxx()方法。由於unittest.TestCase提供了很多內建的條件判斷,我們只需要呼叫這些方法就可以斷言輸出是否是我們所期望的。最常用的斷言就是assertEqual()

self.assertEqual(abs(-1), 1) # 斷言函式返回的結果與1相等

另一種重要的斷言就是期待丟擲指定型別的Error,比如通過d['empty']訪問不存在的key時,斷言會丟擲KeyError

with self.assertRaises(KeyError):
    value = d['empty']

而通過d.empty訪問不存在的key時,我們期待丟擲AttributeError

with self.assertRaises(AttributeError):
    value = d.empty

執行單元測試

一旦編寫好單元測試,我們就可以執行單元測試。最簡單的執行方式是在mydict_test.py的最後加上兩行程式碼:

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

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

$ python mydict_test.py

另一種方法是在命令列通過引數-m unittest直接執行單元測試:

$ python -m unittest mydict_test
.....
----------------------------------------------------------------------
Ran 5 tests in 0.000s

OK

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

setUp與tearDown

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

setUp()tearDown()方法有什麼用呢?設想你的測試需要啟動一個數據庫,這時,就可以在setUp()方法中連線資料庫,在tearDown()方法中關閉資料庫,這樣,不必在每個測試方法中重複相同的程式碼:

class TestDict(unittest.TestCase):

    def setUp(self):
        print('setUp...')

    def tearDown(self):
        print('tearDown...')