27.python的错误(二)—调试、测试

原创 2018年04月17日 21:10:09

1)调试

程序写完后不可避免的有bug,我们需要不断的调试bug以达到程序的完美,那么我们需要一整套的调试程序的手段来修复bug。

(1)print

我们可以直接打印出可能有错误的变量。示例如下:

def fun(s):
    n=int(s)
    print('n=',n)
    return 10/n
if __name__ == '__main__':
   fun('0')

输出结果如下:

(2)assert

assert可以用来代替print。示例代码如下:

def fun(s):
    n=int(s)
    assert n!=0,'n is 0'
    return 10/n
if __name__ == '__main__':
   fun('0')

这里assert的意思是n!=0应该为真,否则就出错。如果assert为假,那么就抛出错误。输出结果如下:

2)测试

(1)单元测试

什么是单元测试呢?比如说我们完成了一个函数abs()。我们编写如下测试程序段:

  • 在输入1,2,3的时候,返回1,2,3。

  • 输入-1,-2,-3的时候,返回1,2,3。

  • 输入0的时候,返回0。

  • 输入非数值类型,返回TypeError。

将以上的程序段放到一个模块里,利用该模块不断试验完善程序的过程叫做单元测试

如果单元测试通过,说明我们测试的这个函数能够正常工作。如果不正确那么需要调试。那么单元测试有什么意义呢?我们在每次对原函数(abs)修改后,可以用单元测试来确保原函数的功能没有被破坏。

举个例子:我们来编写一个Dict类,这个类的行为和dict一致,但是可以通过属性来访问,如下效果:

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
d=Dict(a=1,b=2)
print(d['a'])
print(d.a)

输出结果如下:

接下来,我们编写单元测试模块:

这里我们需要引入python自带的unittest模块,编写test.py如下:

import unittest
from exercise import Dict
class TestDict(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.keys,'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(AttributeError):
            value=d.empty
    def test_atterror(self):
        d=Dict()
        with self.assertRaises(AttributeError):
            value=d.empty
if __name__ == '__main__':
    unittest.main()

输出结果如下:

这里,我们编写了5个测试程序。其中通过了4个,有一个失败了。TestDict类中以test开头的就是测试程序,不是test开头的就不是测试方法,测试的时候不会被执行。对每一类测试都需要编写一个test_xxx()方法。由于unittest.TestCase提供了很多内置的条件判断,我们只需要调用这些方法就可以断言输出是否是我们所期望的。最常用的断言就是assertEqual():

self.assertEqual(abs(-1), 1) # 断言函数返回的结果与1相等

另一种重要的断言就是期待抛出指定类型的Error,比如通过d['empty']访问不存在的Key时,断言会抛出KeyError:

with self.assertRaises(KeyError):
    value = d['empty']

而通过d['empty']访问不存在的Key时,我们期待抛出AttributeError:

with self.assertRaises(AttributeError):
    value = d.empty

(2)文件测试

在Python的官方文档中,很多文档都有示例代码。如re模块就带了很多示例代码:

>>> import re
>>> m=re.search('(?<=abc)def','abcdef')
>>> m.group(0)
'def'

可以把这些示例代码在python的交互式环境下输入并执行,结果与文档中的示例代码显示的一致。这些代码与其他说明可以写在注释中,然后由一些工具来自动生成文档。既然这些代码本身可以粘贴出来直接运行,那么我们不如直接直接运行注释中的代码,何必再粘贴呢?问题是这样可以吗?可以的话,又得怎么做呢?方法如下:

我们在编写注释的时候,写上这样的注释:

def abs(n):
    '''
    Function to get absolute value of number.
    Example:
    >>> abs(1)
    1
    >>> abs(-1)
    1
    >>> abs(0)
    0
    '''
    return n if n >= 0 else (-n)

那么程序员将更加理解这个函数的用法。并且,python内置的"文档测试"(doctest)模块可以直接提取注释中的代码并执行测试。

doctest严格按照python交互式命令行输入和输出来判断测试结果是否正确。只有测试异常的时候,可以用...来表示中间的错误提示输出。

PS:

这里,我们最后用了if __name__='__main__'结构。我们这里补充介绍一下:

一个python.py文件可以有两种使用方法,一种是作为脚本直接执行,另一种就是Import到其他的python脚本中被调用(模块重用)执行。而这段代码的作用就是来区分这两种使用方法:只有在第一种情况下,其冒号后面的代码才会执行。在第二种情况下,当该模块被import到其他脚本下,其冒号后面的代码是不会执行。这里举个例子:

我们在exercise.py中输入以下代码:

print("first")
if __name__=="__main__":
    print("second")

运行该exercise.py,结果如下:

在test.py中输入以下代码:

import exercise

结果如下:

这样结果就很明显了,第一个程序if __name__='__main__'前后面的代码都执行了,第二个程序只执行了前面的代码

希望有志同道合的小伙伴关注我的公众平台,欢迎您的批评指正,共同交流进步。


测试

-
  • 1970年01月01日 08:00

Python学习 (七 错误、调试和测试)

前言:有的错误是程序编写有问题造成的,有的错误是用户输入造成的,还有一类错误是完全无法在程序运行过程中预测的,这类错误也称为异常。跟踪程序的执行,查看变量的值是否正确,这个过程称为调试,Python的...
  • Malus_core
  • Malus_core
  • 2016-05-28 08:10:27
  • 1623

python错误调试和测试

错误调试和测试 在代码编写和运行过程中总会遇到各种错误,这是不可避免的; 错误处理 1、错误基类BaseException类似java的try catch finally和Exception类;t...
  • zocojoker
  • zocojoker
  • 2017-04-05 15:00:26
  • 616

Python学习笔记(二) 之 错误,调试,测试

1.错误处理 2.调试 1) 使用print()打印 def foo(s): n = int(s) print('>>> n = %d' % n) return 10...
  • Thousa_Ho
  • Thousa_Ho
  • 2017-03-30 17:36:02
  • 192

调试、测试和异常处理

  • 2008年11月21日 18:10
  • 2.12MB
  • 下载

Python之错误,调试和测试

1. 错误处理1.1 try …except…1.1.1 try …except…try: print ("try...") r = 10 / 0 print ("result:...
  • zengchen73
  • zengchen73
  • 2017-07-26 10:20:48
  • 170

python之错误、调试和测试

错误 基本错误类型 https://docs.python.org/2/library/exceptions.html#exception-hierarchy try...excep...
  • yt8449960
  • yt8449960
  • 2015-05-06 18:57:02
  • 210

学习笔记_错误、调试和测试

错误、调试和测试_单元测试学习日期:2016年9月28日 学习课程:错误、调试和测试 - 廖雪峰的官方网站错误 在程序运行过程中,总会遇到各种各样的错误。有可能是程序编写的错误,有可能是用户输入的错...
  • weixin_35955795
  • weixin_35955795
  • 2016-09-29 21:53:33
  • 143

python错误、调试和测试

Python内置了一套异常处理机制,来帮助我们进行错误处理。 在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样,就可以知道是否有错,以及出错的原因。在操作系统提供的调用中,返回...
  • qq_26847293
  • qq_26847293
  • 2016-03-02 12:58:01
  • 178

Python 的错误、调试和测试

程序运行中,可能会遇到BUG、用户输入异常数据以及其它环境的异常,这些都需要开发者进行处理。 Python有一套内置的异常处理机制,同时PDB提供了调试代码的功能。 1、错误处理 在一般的程序处理中,...
  • u011559236
  • u011559236
  • 2017-10-10 06:53:29
  • 59
收藏助手
不良信息举报
您举报文章:27.python的错误(二)—调试、测试
举报原因:
原因补充:

(最多只允许输入30个字)