下面开始本书第四部分的读书笔记部分
第四部分 开发中的调试和测试思想
第8章 调试;第9章 极限测试思想
第8章 调试
调试是执行一次成功的测试(发现软件中的错误)之后所要进行的工作。也就是说如果程序测试中发现了问题,就需要程序员对程序进行调试来解决问题。调试包括两个部分:定位问题和修改错误。测试到调试的关系图如下所示
因为对错误进行定位可能就已经解决大部分的问题,所以本章着重讨论定位错误的几种方法;然后,通过本章总结的一些调试原则,告诉读者最有效的调试方法,是在调试时进行“思考!”,只有这样才能高效的调试和解决问题;最后,作者告诉读者,光会调试还是不够的,还需要对错误进行分析,进而获取改进设计和测试过程的有价值信息。
1、暴力法调试
此方法很流行,我调试程序也经常用这类方法,因为它不需要过多思考,不费脑子,但是效率低下。只有在其他方法都失败或者作为替代方法进行调试。
1)利用内存信息输出来调试
如果做嵌入式设备,因为地址中内容是16进制数据,可能会查看Flash地址中的内容,来调试程序。但这种方法极其低效。
2)在程序中插入打印语句来调试
如果是嵌入式设备,可能还会添加亮灯、蜂鸣或串口打印等方式;
如果是小型应用程序,可以将每次产生的数据通过日志形式输出,根据日志内容来确定问题,分析问题和解决问题;
但是对大型程序,如操作系统、过程控制软件,就很难应用。
3)自动化调试工具
使用编程语言的调试功能,类似于在程序中插入打印语句,只是不修改程序本身。
比如Visual StudioIDE、Keil MDK等集成开发环境,通过设置断点、跟程序进行调试。
2、归纳法调试
从名字可以看出,归纳法其实是一种思考的过程,是一种从特殊到一般,从线索(错误的现象,或测试用例的结果)出发,找出线索之间联系,进而解决问题。
有如下5个步骤:1.确定相关数据;2.组织数据;3.作出假设;4.证明假设;5.解决问题。
1) 确定相关数据
将所有可能的数据或现象均考虑进去,正确和不正确的数据和现象都需要得到;
2)组织(解析)获取的数据
通过组织相关数据,以便观察数据之间的关系,进而对数据进行解析,解析数据的方法可以按照,“是什么”、“在何处”,“在何时”,“多大程度”进行分析。
“是什么”,对症状或现象的描述;“在何处”,描述这些症状出现的位置;“在何时”,描述这些症状什么时候发生;“多大程度”,描述这些症状的范围和重要性;注意“是”,“否”列,描述的矛盾之处最终可能会导致对错误的假设。
? | 是 | 否 |
是什么 | 测试用例3中显示中间值不正确 | |
在何处 | 仅在测试用例3中出现 | 学生成绩计算似乎正确 |
何时 | 当测试学生数量为51时发生 | 测试学生数量为2或200时未发生 |
多大程度 | 显示的中间值为26。当学生数量为1时也同样发生,显示的中间值为1 |
3)做出假设
这时候需要研究线索之间的联系,假设一下产生错误的原因,如果找不出来,则需要更多数据;
4)证明假设
将假设同最初的线索或数据进行比较,看看假设是否具有合理性,如果假设无效,则需要重新构造假设,或需要更多数据;
5)解决问题
完成前面几步后,则可以修复这个问题。有一条需要记住:做回归测试,确保修复错误的同时没有引入其他新的错误。
3、演绎法调试
演绎法:是从一般理论或前提出发,使用排除法,提炼剩余的假设,进而达到结论(错误的位置)。
与归纳法正好相反,演绎法是先找出所有可能的原因或假设,然后排除不可能的原因或假设,最后剩下的那个原因可能就是最终的结论。
演绎法调试有以下几个步骤:1.找出所有可能的原因或假设;2.排除不可能的原因或假设;3.提炼剩下的假设;4.证明剩下的假设;5.修改错误(解决问题)。
1)列举出所有可能的原因或假设
当收集到有问题的数据时,需要先列出数据出现问题的原因或假设的列表(仅仅是猜测)。
2)利用数据排除掉不可能的原因
利用归纳法调试中解析数据的方法(是什么,在哪里,在何时,多大程度上)排除掉不可能的原因,剩下的原因可能就是真正的原因。当所有原因都排除掉了,需要设计新的测试用例。
3)提炼剩下的假设
剩下的假设也许是正确的,但是不够具体,可以根据当前有的线索,将假设具体化。
4)证明剩下的假设
将假设同最初的线索或数据进行比较,看看假设是否具有合理性,如果假设无效,则需要重新构造假设,或需要更多数据;
5)修改错误(解决问题)
完成前面几步后,则可以修复这个问题,有一定需要记住:做回归测试,确保修复的错误没有引入其他新的错误。
4、回溯法调试
此方法一般用在小型程序中进行错误定位。
当发现错误后,可以从出现错误的位置开始,开始逆向执行程序,直到找出程序逻辑出错的位置。
重复使用“如果程序在此处的状态是这样,那么程序在上面的位置的状态就必然是那样的”过程,可以很快定位错误。
5、测试法调试
两种测试用例:供测试用的测试用例;供调试用的测试用例。
供测试用的测试用例:目的是暴露出以前尚未发现的错误,涵盖的条件较多;供调试用的测试用例:目的是提供有用信息,供定位某个被怀疑的错误之用,涵盖的条件较少。
当发现某个测试用例发现了错误,需要编写与原先有变化的(瘦身的)测试用例,尽量确定错误的位置。
工作中这种方法也可以叫做:复现问题,通过设计一种与原来的测试用例相似的用例,让错误再次发生。
结合归纳法使用,获得进行或证明假设的信息;结合演绎法使用,排除有嫌疑的原因,提炼剩下的假设,并证明假设。
6、调试的原则
调试原则,实质上也是心理学的原则。调试过程分定位错误和修改错误。
6.1 定位错误原则
1)动脑筋
调试是一个解决问题的过程,最有效的调试方法是动脑筋对错误症状的有关信息进行分析,以下列出一些思考的诀窍。
-
- 让自己置身于安静、没有干扰的环境中
- 不看代码,在脑海中思考程序是怎么设计,并思考表现异常的地方本该是什么样的
- 将注意力集中在思考程序正确行为的过程上,并想象那些可能导致错误设计的代码实现方式
2)如果遇到了僵局,就留到稍后解决
如果在合理时间内(小程序30分钟,大程序1个小时),还不能定位问题,就离开它,做些其他的事情。
忘记这个问题一段时间后,再重新检查问题的症状,思维会焕然一新。
不仅调试,开发过程也可以这样。
3)如果遇到了困境,就把问题描述给其他人听
与其他人交谈可能会帮助我们发现一些新的东西。
仅仅将问题描述给倾听者,而无须倾听者提供任何帮助,就会突然找到问题的解决之道。
4)仅将调试工具作为第二中手段
在试过其他方法后才是用调试工具。
将调试工具作为头脑思考的辅助手段,而不是替代手段。因为对工具的过分依赖,可能减少对已经获得的线索的关注,可能这些线索就能帮你直接解决问题。
5)避免使用试验法--仅将其作为最后的手段
不要为了调试程序而去试验性地去修改程序。
6.2 修改错误的技术
1)存在一个缺陷的地方,很有可能还存在其他缺陷
因为错误有扎堆出现的倾向。在修改某个问题的同时,应检查一下紧邻的地方,看看有没有可能是错误之处。
2)应纠正错误本身,而不仅是其症状
应从根本上解决问题,而不应该只修改错误的一部分。
3)正确纠正错误的可能性并非100%
应对错误的修改进行测试,也许比对原先程序的测试还要严格(回归测试)。
4)随着程序规模的增加,正确修改错误的可能性反而降低
经验:由于修改不正确而引入的错误与原始错误之比,在规模较大的程序中呈递增趋势。对于广泛使用的大程序,每发现6个新错误,就有1个错误是由于先前对程序的改正而造成的。
5)应意识改正错误会引入新错误的可能性
对错误的修改点进行测试,同时应执行回归测试。
6)修改错误的过程也是临时回到设计阶段的过程
在设计阶段使用的任何规程、方法和形式都同样适用于错误修改阶段。例如,项目证明代码检查很管用,那么在修改错误之后进行代码检查就显得倍加重要。
7、错误分析
调试除了消灭程序中的错误,还告诉我们软件错误的本质,这些软件错误本质的信息可以为改进将来的设计、编码和测试过程提供有价值的反馈。
通过详细分析发现的错误,可以获得关于软件有价值的信息,详细的错误分析包括:
1)错误出现在什么地方?
通过对程序文档和项目历史进行追溯,找到该错误的源头和发生时间。
比如,错误源头可能是:1.规格说明书中模棱两可语句;2.对上次错误的修改;3.对最终用户需求的错误理解。
2)谁制造了这个错误?
如果30%的错误都是某个程序员产生,不是很有用吗?(不是为了惩罚,而是为了进行培训)
3)哪些做得不正确?
需要判断错误发生的原因。比如,1.错误是由于某人写得不清楚;2.错误是由于某人缺乏对编程语言的培训;3.错误是打字错误;4.错误假设做得不对;5.错误是没有考虑有效输入;
4)如何避免该错误的出现?
在下一个项目中应如何避免该问题的出现?(这就是最宝贵的经验和信息)
5)为什么错误没有早些发现?
如果错误是在测试阶段发现的,需要研究:为什么更早的测试阶段、代码审查和设计阶段中没有发现错误。
6)该如何更早地发现错误?
如何改进评审和测试过程,以便在将来的项目中更早发现同类型的错误。
通过对错误进行分析,可以积攒开发和测试的经验,保证质量的同时节省开发和维护的成本。
综上,本章首先介绍了一些软件调试的方法,包括暴力法调试、归纳法调试、演绎法调试、回溯法调试和测试法调试;然后,介绍一些定位错误和修改错误的技术原则,帮助读者更快速和更高效的进行调试;最后,作者介绍一些对错误进行分析的方法,为将来改进软件质量提供有价值的信息。
发现在工作中这些调试方法都会使用,只是没有像书中那样汇总的那么全面;同时工作中使用最多的也还是暴力调试法,如果想获得提升和进步,还是需要使用一些需要引发自己思考的方法(归纳法和演绎法等),不过这一切的基础都是构建在自己对程序本身的了解和掌握上(程序还是要认真的看滴,不要认为测试就不要看程序)。
来源:oschina
链接:https://my.oschina.net/u/4406506/blog/3431696