Python基础知识(20):错误、调试和测试
一、错误处理
在运行程序的过程中有可能会出错,一般我们会在添加一段代码在可能出错的地方,返回约定的值,就可以知道会不会出错以及出错的原因
1、使用try......except......finally......错误处理机制
try...可能会出异常的代码
except...如果try后面的代码出错,则运行这里的语句;否则直接运行finally语句
finally...无论try语句是否出错都会运行
try: z=5/0 print("ressult=",zip) except ZeroDivisionError: print("The second number can't be number!") finally: print("I'm here.") The second number can't be number! I'm here.
多个except语句
try: z=5/5 print("ressult=",z) except ValueError as e: print('ValueError:', e) except ZeroDivisionError as e: print('ZeroDivisionError:', e) else: print('No error!') finally: print("I'm here.")
2、记录错误
使用logging模块可以记录出错信息
通过配置,可以让logging记录出错的信息到日志,以便日后排查
#testlog.py
import logging def test(x): return 5/int(x) def main(): try: test("0") except Exception as e: logging.exception(e) main() print("END")
同样是出错,但程序打印完错误信息后会继续执行,并正常退出
ERROR:root:division by zero Traceback (most recent call last): File "D:/Python/doit/testLog.py", line 7, in main test("0") File "D:/Python/doit/testLog.py", line 4, in test return 5/int(x) ZeroDivisionError: division by zero END
3、抛出错误
使用raise语句
如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise
语句抛出一个错误的实例
#testError class testError(ValueError): pass def test(x): y = int(x) if y==0: raise testError('invalid value: %s' % x) return 10 / y test('0') Traceback (most recent call last): File "D:/Python/doit/testError.py", line 11, in <module> test('0') File "D:/Python/doit/testError.py", line 8, in test raise testError('invalid value: %s' % x) testError: invalid value: 0
注:只有为完成某些需要时我们才自己定义错误类型,日常一般使用Python内置的错误类型
二、调试
1、用print打印能出错的变量
2、断言assert
使条件为真,保证程序正常运行下去,否则抛出AssertionError
可以在条件后添加字符串,用来解释断言
def test(x): y=int(x) assert y!=0,"y is zero" return 5/y def main(): test("0") main() Traceback (most recent call last): ...... AssertionError: y is zero
3、logging
允许指定记录出错信息的日志级别等级:critical > error > warning > info > debug
#logErro.py import logging logging.basicConfig(level=logging.INFO) x="0" y=int(x) ogging.info("y=%d"%y) print(5/y) Traceback (most recent call last): File "D:/Python/doit/logErro.py", line 6, in <module> ogging.info("y=%d"%y) NameError: name 'ogging' is not defined
4、pdb
Python调试器,需要单步执行
5、pdb.set_trace
这个方法也是用pdb,但是不需要单步执行,只需要import pdb
,然后在可能出错的地方放一个pdb.set_trace()
,就可以设置一个断点
6、IDE
可以设置断点、单步执行
需要安装Python IDE
三、测试
单元测试
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作
这种以测试为驱动的开发模式最大的好处就是确保一个程序模块的行为符合我们设计的测试用例。在将来修改的时候,可以极大程度地保证该模块行为仍然是正确的
单元测试可以有效地测试某个程序模块的行为,是未来重构代码的信心保证
单元测试的测试用例要覆盖常用的输入组合、边界条件和异常
单元测试代码要非常简单,如果测试代码太复杂,那么测试代码本身就可能有bug
单元测试通过了并不意味着程序就没有bug了,但是不通过程序肯定有bug
setUp与tearDown
可以在单元测试中编写两个特殊的setUp()
和tearDown()
方法。这两个方法会分别在每调用一个测试方法的前后分别被执行
文档测试
Python内置的“文档测试”(doctest)模块可以直接提取注释中的代码并执行测试
当模块正常导入时,doctest不会被执行。只有在命令行直接运行时,才执行doctest。所以,不必担心doctest会在非测试环境下执行
doctest非常有用,不但可以用来测试,还可以直接作为示例代码。通过某些文档生成工具,就可以自动把包含doctest的注释提取出来。用户看文档的时候,同时也看到了doctes