八错误调试与测试
Posted liqiongming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了八错误调试与测试相关的知识,希望对你有一定的参考价值。
1、错误处理
- try...except...(finally...):finally可不写,可加‘else’表在没有错误时执行else下的内容
1 try: 2 r = 10 / 0 3 print(‘result:‘,r) 4 except ZeroDivisionError as e: 5 print(‘Error:‘,e) 6 # except ZeroDivisionError: 7 # print(‘除数不能为零。‘) 8 finally: 9 print(‘End‘) 10 11 输出: 12 Error: division by zero 13 #除数不能为零。 14 End
- 调用栈:没有捕捉错误时,需分析错误的调用栈信息,才能定位错误的位置(即打印时报错的内容)
- 记录错误(logging):能记录错误信息,能把错误堆栈打印出来并继续执行程序。(可用于将错误信息记录在日志中)
1 import logging 2 def foo(s): 3 return 10 / int(s) 4 def bar(s): 5 return foo(s) * 2 6 def main(): 7 try: 8 bar(‘0‘) 9 except Exception as e: 10 logging.exception(e) 11 12 main() 13 print(‘END‘) 14 15 输出: 16 END 17 ERROR:root:division by zero 18 Traceback (most recent call last): 19 File "D:/Pycharm...(略) 20 ...line 469, in foo 21 return 10 / int(s) 22 ZeroDivisionError: division by zero
- 抛出错误(raise):根据需要,定义一个错误的class,选择好继承关系,然后用
raise
语句抛出一个错误的实例1 #定义一个错误的类 2 class FooError(ValueError): 3 pass 4 def foo(s): 5 n = int(s) 6 if n == 0: 7 # 追踪到自己定义的错误信息 8 raise FooError(‘invalid value:%s‘ %s) 9 return 10 / 0 10 foo(‘0‘) 11 12 输出: 13 Traceback (most recent call last): 14 File "D:/Pycharm/廖雪峰课程/函数.py", line 460, in <module> 15 foo(‘0‘) 16 File "D:/Pycharm/廖雪峰课程/函数.py", line 458, in foo 17 raise FooError(‘invalid value:%s‘ %s) 18 __main__.FooError: invalid value:0 #raise的内容
- 调试:
- assert(断言):表达式应该为True,断言错误抛出AssertError错误(启动Python解释器时可以用
-O
参数来关闭assert
)1 def func(s): 2 n = int(s) 3 assert n != 0,‘n is zero!‘ 4 return 10 / n 5 def main(): 6 func(‘0‘) 7 main() 8 9 输出: 10 Traceback (most recent call last): 11 File "D:/Pycharm... 12 ...(略) 13 assert n != 0,‘n is zero!‘ 14 AssertionError: n is zero!
- logging:不会抛出错误,可指定记录信息的级别,有
debug
,info
,warning
,error
等几个级别1 import logging 2 logging.basicConfig(level=logging.INFO) 3 s = ‘0‘ 4 n = int(s) 5 logging.info(‘n = %d‘%n) 6 print(10/n) 7 8 输出: 9 INFO:root:n = 0 10 Traceback (most recent call last): 11 File "D:/...(略) 12 print(10/n) 13 ZeroDivisionError: division by zero
- pdb:调试器pdb,让程序以单步方式运行,可以随时查看运行状态。以参数-m pdb启动后,命令: l 查看代码;n 单步执行代码;p + 变量名 查看变量;q 结束调试。
- pdb.set_trace():放在可能出错的地方,设置一个断点,不需要单步执行,命令 c 继续运行。
1 import pdb 2 s = ‘0‘ 3 n = int(s) 4 pdb.set_trace() 5 print(10/n) 6 7 输出: 8 > d:pycharm...<module>() 9 -> print(10/n) 10 (Pdb) p n 11 0 12 (Pdb) q
- 单元测试:使用了assertEqual断言与错误处理。(setUp与tearDown之间的内容会在每段测试前后被执行一遍,如测试需要启动一个数据库,可在
setUp()
方法中连接数据库,在tearDown()
方法中关闭数据库,这样做可不必在每个测试方法中重复相同的代码)1 #func.py文件 2 class Dict(dict): 3 def __init__(self,**kw): 4 super().__init__(**kw) #调用父类的init方法 5 def __getattr__(self, key): #设置返回属性值key 6 try: 7 return self[key] 8 except KeyError: 9 raise AttributeError(r"‘Dict‘ object has no attribute ‘%s‘" % key) 10 def __setattr__(self,key,value): 11 self[key] = value
1 #用于测试的类(test.py) 2 import unittest 3 from func import Dict 4 class Testdict(unittest.TestCase): #测试类需继承unittest.TestCase 5 # def setUp(self): 6 # print(‘setup...‘) 7 def test_init(self): 8 d = Dict(a = 1,b = ‘test‘) 9 self.assertEqual(d.a,1) #断言d对象中a属性的值是否为1 10 self.assertEqual(d.b,‘test‘) 11 self.assertTrue(isinstance(d,dict)) 12 13 def test_key(self): #测试key 14 d = Dict() 15 d[‘key‘] = ‘value‘ 16 self.assertEqual(d[‘key‘], ‘value‘) 17 18 def test_attr(self): #测试属性 19 d = Dict() 20 d.key = ‘value‘ 21 self.assertTrue(‘key‘ in d) 22 self.assertEqual(d.key, ‘value‘) 23 24 25 # 通过d[‘empty‘]访问不存在的key时,抛出指定类型的Error 26 def test_keyerror(self): #抛出key错误 27 d = Dict() 28 with self.assertRaises(KeyError): 29 value = d[‘empty‘] 30 31 def test_attrerror(self): #抛出属性错误 32 d = Dict() 33 with self.assertRaises(AttributeError): 34 value = d.empty 35 36 # def tearDown(self): 37 # print(‘tearDown...‘) 38 39 if __name__ == ‘__main__‘: #使该文件当做正常脚本运行 40 unittest.main() 41 42 43 输出: 44 Testing started at 16:15 ... 45 D:Py...(略) 46 #setUp与tearDownd 内容 47 Ran 5 tests in 0.002s 48 49 OK
- 文档测试:运行没内容输出时说明编写的doctest运行都是正确的。更明确地告诉函数的调用者该函数的期望输入和输出,内置的 doctest 模块可以直接提取注释中的代码并执行测试,测试异常的时候,可以用
...
表示中间内容的输出。1 class Dict(dict): 2 ‘‘‘ 3 Simple dict but also support access as x.y style. 4 5 >>> d1 = Dict() 6 >>> d1[‘x‘] = 100 7 >>> d1.x 8 100 9 >>> d1.y = 200 10 >>> d1[‘y‘] 11 200 12 >>> d2 = Dict(a=1, b=2, c=‘3‘) 13 >>> d2.c 14 ‘3‘ 15 >>> d2[‘empty‘] 16 Traceback (most recent call last): 17 ... 18 KeyError: ‘empty‘ 19 >>> d2.empty 20 Traceback (most recent call last): 21 ... 22 AttributeError: ‘Dict‘ object has no attribute ‘empty‘ 23 ‘‘‘ 24 def __init__(self, **kw): 25 super(Dict, self).__init__(**kw) 26 27 def __getattr__(self, key): 28 try: 29 return self[key] 30 except KeyError: 31 raise AttributeError(r"‘Dict‘ object has no attribute ‘%s‘" % key) 32 33 def __setattr__(self, key, value): 34 self[key] = value 35 36 if __name__==‘__main__‘: 37 import doctest 38 doctest.testmod()