調(diào)試
- try:當(dāng)我們認(rèn)為某些代碼可能會出錯時,就可以用try來運行這段代碼,如果執(zhí)行出錯,則后續(xù)代碼不會繼續(xù)執(zhí)行,而是直接跳轉(zhuǎn)至錯誤處理代碼,即except語句塊,執(zhí)行完except后,如果有finally語句塊,則執(zhí)行finally語句塊,至此,執(zhí)行完畢。
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally...')
print('END')
- 記錄錯誤:如果不捕獲錯誤,自然可以讓Python解釋器來打印出錯誤堆棧,但程序也被結(jié)束了。既然我們能捕獲錯誤,就可以把錯誤堆棧打印出來,然后分析錯誤原因,同時,讓程序繼續(xù)執(zhí)行下去。
# err_logging.py
import logging
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('0')
except Exception as e:
logging.exception(e)
main()
print('END')
- 拋出錯誤:,可以定義一個錯誤的class,選擇好繼承關(guān)系,然后,用raise語句拋出一個錯誤的實例。
# err_raise.py
class FooError(ValueError):
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)
return 10 / n
foo('0')
單元測試
用來對一個模塊、一個函數(shù)或者一個類來進行正確性檢驗的測試工作。
我們來編寫一個Dict類,這個類的行為和dict一致,但是可以通過屬性來訪問,用起來就像下面這樣
>>> d = Dict(a=1, b=2)
>>> d['a']
1
>>> d.a
1
# 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
import unittest #引入模塊
from mydict import Dict
class TestDict(unittest.TestCase): #繼承unittest.TestCase
def test_init(self):
d = Dict(a=1, b='test')
self.assertEqual(d.a, 1)
self.assertEqual(d.b, 'test')
self.assertTrue(isinstance(d, dict))
def test_key(self):
d = Dict()
d['key'] = 'value'
self.assertEqual(d.key, 'value')
def test_attr(self):
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 = d['empty']
def test_attrerror(self):
d = Dict()
with self.assertRaises(AttributeError):
value = d.empty
- 運行單元測試
1.一旦編寫好單元測試,我們就可以運行單元測試。最簡單的運行方式是在mydict_test.py的最后加上兩行代碼
if __name__ == '__main__':
unittest.main()
$ python3 mydict_test.py
2.另一種方法是在命令行通過參數(shù)-m unittest直接運行單元測試:
$ python3 -m unittest mydict_test
- setUp與tearDown
可以在單元測試中編寫兩個特殊的setUp()和tearDown()方法。這兩個方法會分別在每調(diào)用一個測試方法的前后分別被執(zhí)行。
class TestDict(unittest.TestCase):
def setUp(self):
print('setUp...')
def tearDown(self):
print('tearDown...')
文檔測試
# mydict2.py
class Dict(dict):
'''
Simple 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()
python3 mydict2.py
什么輸出也沒有。這說明我們編寫的doctest運行都是正確的。