《编程导论》 CH6 测试和调试
6.1 测试
测试套件
划分
白盒测试 - 考察代码结构
黑盒测试 - 探索需求路径、测试边界条件
单元测试 vs 集成测试
测试桩和驱动程序
回归测试
6.2 调试
运行时的错误:
显式->隐式
持续->间歇
研究现有数据
提出假设、设计实验
减小搜索空间->二分查找
一些常见的问题,如:
传入函数的参数顺序错误
写错了名称,如把大写字母写成了小写字母
忘记了重新初始化变量
使用相等(==)而不是近似相等来测试两个浮点值
使用值相等(如L1==L2来比较两个列表)来判断对象相等(如id(L1)==id(L2))
忘记了一些内建函数有副作用
忘记了()会把函数类型对象的引用转换为函数调用
不小心创建了别名
其他
遇到阻碍时的一些忠告:
不要问自己程序为什么不按照你的想法工作,反之应问为什么程序会像现在这样工作
错误可能不在你认为的地方
试着向其他人解释错误
不要相信你读到的任何东西,尤其是文档
停止调试,开始开始编写文档
散散步,明天再来
找到错误后:
考虑错误是否可以解释所有观察到的问题
修改之前考虑可能产生的后果
及时备份,确保可以回退
等等
CH7 异常和断言
7.1 处理异常
例子
除零错误:
try:
successFailureRatio = numSuccesses/float(numFailures)
print 'The success/failure ratio is', successFailureRatio
except ZeroDivisionError:
print 'No failures so the success/failure ratio is undefined.'
print 'Now here'
ValueError:
while True:
val = raw_input('Enter an integer: ')
try:
val = int(val)
print 'The square of the number you entered is',val**2
break
except ValueError:
print val,' is not an integer'
except(ValueError,TypeError):
7.2 把异常当作控制流来使用
在许多编程语言中,标准的错误处理方法是让函数返回一个值(类似Python中的None)来表示出错。每个函数调用都需要检查返回值。在Python中若函数不能产生满足需求的结果,更常见的方法是让函数触发一个异常。
python的raise语句会强制触发一个指定的异常。形式为: raise exceptionName(arguments)
不同类型的异常可以接受不同类型的参数,而多数时候只是一个字符串,用来描述异常触发的原因
例子:
def getRatios(vect1,vect2):
"""assume vect1 and vect2 are lists with same length,
return a list, in which each element is vect1[i]/vect2[i]"""
ratios = []
for index in range(len(vect1)):
try:
ratios.append(vect1[index]/float(vect2[index]))
except ZeroDivisionError:
ratios.append(float('nan')) #nan=Not a Number
except:
raise ValueError('getRatios called with bad arguments')
return ratios
try:
print getRatios([1.0,2.0,7.0,6.0],[1.0,2.0,0.0,3.0])
print getRatios([],[])
print getRatios([1.0,2.0],[3.0])
except ValueError,msg:
print msg
结果:
[1.0, 1.0, nan, 2.0]
[]
getRatios called with bad arguments
另外一个例子:
def getGrades(fname):
try:
gradesFile = open(fname,'r') #open file for reading
except IOError:
raise ValueError('getGrades could not open '+fname)
grades = []
for line in gradesFile:
try:
grades.append(float(line))
except:
raise ValueError('Unable to convert line to float')
return grades
try:
grades = getGrades('quiz1grades.txt')
grades.sort()
median=grades[len(grades)//2]
print 'Median grade is',median
except ValueError,errorMsg:
print 'Whoops.',errorMsg
assert语句 两种形式:
assert Boolean expression
assert Boolean expression, argument
执行assert语句时,会对布尔表达式进行求值。如果为true,继续执行。如果为false,会触发一个AssertionError异常。