python学习(十一)测试和调试

最近学习了python的错误处理和几种测试方法

1 try except

可以通过try except方式捕捉异常

try:
    print('try...')
    r = 10/0
    print('result is :', r)
except ZeroDiversionError as e:
    print('except is :', e)
finally:
    print('finally ...')
print('END')

  可以捕捉不同类型的错误,编写多个except

try:
    print('try...')
    r = 10/int('a')
    print('result is: ', r)
except ValueError as e:
    print('ValueError : ', e)
except ZeroDiversionError as e:
    print('ZeroDivisionError is : ', e)
finally:
    print('finally ...')
print('END')

  try except同样支持else结构

try:
    print('try... ')
    r = 10/int('2')
    print('result is : ', r)
except ValueError as e:
    print('ValueError : ', e)
except ZeroDivisionError as e:
    print('ZeroDivisionError is : ', e)
else:
    print('no error')
finally:
    print('finally ...')
print('END')

  某个函数调用出现异常,在上层同样可以捕获到

def foo(s):
    return 10/int(s)
def bar(s):
    return  foo(s) * 2
def main():
    try:
        bar('0')
    except Exception as e:
        print('Exception is : ', e)
    finally:
        print('finally...')
main()

  

2 logging

python 提供打日志方式输出异常,并且不会因为出现异常导致程序中断

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')

  

如果想要将异常处理的更细致,可以自定义一个异常类,继承于几种错误类,如ValueError等,在可能出现问题的地方将错误抛出来

class FooError(ValueError):
    pass
def foo(s):
    n = int(s)
    if n == 0:
        raise FooError('invalid error is : %s' %s)
    return 10/n
foo('0')

  错误可以一层一层向上抛,直到有上层能处理这个错误为止

def foo(s):
    n = int(s)
    if n==0:
        raise ValueError('invalid error is: %s' %s)
    return 10/n
def bar():
    try:
        foo('0')
    except ValueError as e:
        print('ValueError')
        raise
bar()

  logging可以设置不同的级别,通过basicConfig可以设置

import logging 
logging.basicConfig(level=logging.INFO)
def foo(s):
    n = int(s)
    return 10/n
def main():
    m = foo('0')
    logging.info('n is : %d' %m)
main()

  

3 断言assert

大部分语言都支持assert,python也一样,在可能出错的地方写assert,会在异常出现时使程序终止

def foo(s):
    n = int(s)
    assert n != 0 ,'n is zero'
    return 10/n
def main():
    foo('0')
main()

 

4 pdb调试和set_trace

pdb调试用 python -m pdb 文件名.py, 单步执行敲n,退出为q
python 可以在代码里设置断点,在程序自动执行到断点位置暂停,暂停在set_trace的代码行

 

import pdb
def foo(s):
    n = int(s)
    pdb.set_trace()
    return 10/n
def main():
    m = foo('0')
main()

  

5 单元测试

先实现一个自己定义的Dict类,将文件保存为mydict.py

class Dict(dict):
    def __init__(self, **kw):
        super(Dict, self).__init__(**kw)
    def __getattr__(self, key):
        try:
            return self[key]
        except Exception as e:
            raise AttributeError('AttributeError is :%s', e)
    def __setattr__(self, key, value):
        self[key] =  value

  python 提供了单元测试的类,开发者可以继承unittest.Test实现特定的测试类,下面实现Dict的单元测试类,保存为unittestdict.py

import unittest
from mydict import Dict
class TestDict(unittest.TestCase):
	def setUp(self):
		print('setUp...')
	def tearDown(self):
		print('tear Down...')
	def test_init(self):
		d = Dict(a='testa', b = 1)
		self.assertEqual(d.a, 'testa')
		self.assertEqual(d.b, 1)
		self.assertTrue(isinstance(d, dict))
	def test_key(self):
		d = Dict()
		d['name'] = 'hmm'
		self.assertEqual(d.name, 'hmm')
	def test_attr(self):
		d = Dict()
		d.name = 'hmm'
		self.assertEqual(d['name'], 'hmm')
		self.assertTrue('name' in d)
	def test_attrerror(self):
		d = Dict()
		with self.assertRaises(AttributeError):
			value = d.empty
	
	def test_keyerror(self):
		d = Dict()
		with self.assertRaises(AttributeError):
			value = d['empty']
	
if __name__ == '__main__':
	unittest.main()

  运行unittest.py可以检测mydict中Dict类是否有错误

6 文档测试

文档测试在代码中按照特定格式编写python输入和期待的输出,通过python提供的文档测试类,实现测试代码的目的

class Dict(dict):
	'''
	>>> d1 = Dict()
	>>> d1['x'] = 100
	>>> d1.x
	100
	>>> d1.y = 200
	>>> d1['y']
	200
	>>> d2=Dict(a=1,b=2,c='m')
	>>> d2.c
	'm'
	
	'''
	def __init__(self, **kw):
		super(Dict,self).__init__(**kw)
	def __getattr__(self,key):
		try:
			return self[key]
		except KeyError:
			raise AttributeError('AttributeError key is %s' %key)
	def __setattr__(self,key,value):
		self[key] = value
if __name__ == '__main__':
	import doctest
	doctest.testmod()

  我的公众号谢谢关注:

原文地址:https://www.cnblogs.com/secondtonone1/p/7562718.html