# 錯誤 異常 調試 測試
## 調試
### 單元測試 unittest模塊
> 作用 :確保開發/修改后 一個程序模塊的行為符合我們設計的測試用例
# mydict_test.py
class TestDict(unittest.TestCase):
def test_init(self):
d = Dict(a=1, b='test')
self.assertEquals(d.a, 1)
self.assertEquals(d.b, 'test')
self.assertTrue(isinstance(d, dict))
def test_key(self):
d = Dict()
d['key'] = 'value'
self.assertEquals(d.key, 'value')
def test_attr(self):
d = Dict()
d.key = 'value'
self.assertTrue('key' in d)
self.assertEquals(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
def setUp(self): # 每調用一個測試方法前執行 比如連接數據庫
print 'setUp...'
def tearDown(self): # 后執行
print 'tearDown...'
if __name__ == '__main__':
unittest.main()
運行測試腳本
python mydict_test.py
另一種更常見的方法是在命令行通過參
python -m unittest mydict_test # 可以批量運行很多單元測試
test開頭的方法是測試方法
判斷條件:
assertEquals 是否相等
assertRaises 異常類型判斷
> note: 測試用例要覆蓋常用的輸入組合 邊界條件和異常;測試程序要簡單 否則測試代碼本身就可能有bug;測試通過也可能有bug 但不通過肯定有bug
### 單步調試 pdb
python -m pdb err.py
l #查看代碼
n #單步執行
p 變量名 #查看變量
q 結束調試
pdb.set_trace() # 設置斷點 運行到這里會自動暫停(不需要命令行指定pdb)
c 繼續運行
### 日志 logging
logging.basicConfig(level=logging.INFO)
logging.info()
debug info warning error # level 向后兼容
### 斷言 python -o xxx.py 關閉斷言
> 想打印變量看看是否符合預期? 用斷言
> 如果斷言失敗 拋出 *AssertionError* 異常
assert n != 0, 'n is zero!'
assert 條件(應該為True),錯誤信息
## 異常處理
### 各種錯誤
1. 程序錯誤 是bug (只能修改程序)
2. 用戶輸入等因素造成的錯誤 (可以做相應檢查處理)
3. 磁盤滿了 網絡斷了等無法預測的錯誤 稱之為**異常** (可以做相應處理)
所有錯誤類型都繼承自 BaseException
try:
pass
except IndexError,e:
pass
except Exception,e:
logging.exception(3) # 可以記錄錯誤信息
else: # 沒有發生錯誤是會執行
pass
finally: # 無聊是否有錯誤 都要執行
pass
發生錯誤后根據調用棧 一直向上拋出異常 可以在上層捕獲
如果沒有捕獲解釋器就會打印錯誤信息并退出
當程序/數據不符合預期的時候 你可以選擇**拋出異常**
raise FooError('invalid value: %s' % s) # class FooError(StandardError) 自定義錯誤
### 內置類型錯誤
* StandardError
* ValueError
* TypeError