|
测试的目的是为了发现尽可能多的错误,而对于所暴露的错误最终需要被改正。调试的任务就是根据测试时所发现的错误,找出原因和具体的位置,并进行改正。
|
|
|
正如前面所讲的单元测试通常由程序开发人员来进行,对于组装测试、确认测试可以由开发商组织的测试人员或第三方测试中心来进行,在系统测试时需要用户参与共同完成。其原则是除单元测试以外,测试工作应避免由原开发人员或小组来承担。但调试工作主要由程序开发人员来进行,也就是说,谁开发的程序由谁进行调试。
|
|
|
|
调试的过程如下图所示。首先执行设计的测试用例,对测试结果进行分析,如果有错误,需要运用调试技术,找出错误原因和具体的位置。调试结果有两个:一是能确定错误原因并进行了纠正,为了保证错误已排除,需要重新执行暴露该错误的原测试用例以及某些回归测试(即重复一些以前做过的测试);另一种是未找出错误原因,那么只能对错误原因进行假设,根据假设设计新的测试用例证实这种推测。若推测失败,需进行新的推测,直至找到错误并纠正。通常确定错误原因和具体的位置所需的工作量在调试过程中是非常大的,大约占调试总工作量的95%,而且花费的时间也不确定。
|
|
|
|
|
|
无论哪种调试方法,其目的都是为了对错误进行定位。目前常用的调试方法有如下几种。
|
|
|
|
调试人员分析错误的症状,猜测问题的位置所在,利用在程序中设置输出语句,分析寄存器、存储器的内容等手段来获得错误的线索,通过一步步的试探和分析来找到错误所在。这种方法效率很低且缓慢,适合于结构比较简单的程序。
|
|
|
|
调试人员从发现错误症状的位置开始,人工沿着程序的控制流程往回跟踪程序代码,直到找出错误根源为止。这种方法适合于小型程序,对于大规模程序,由于其需要回溯的路径太多而变得不可操作。
|
|
|
|
这种方法主要用来缩小错误的范围。如果已经知道了程序中的变量在若干位置的预期正确取值,可以在这些位置上用赋值语句或输入语句,给这些变量以正确值,运行程序观察输出结果。如果没有发现问题,则说明从给的变量的正确值开始到输出结果之间的程序没有出错,问题可能在于除此之外的程序中,否则错误就在所考察的这部分程序中。对含有错误的程序段再使用这种方法,直到把故障范围缩小到比较容易诊断为止。
|
|
|
|
归纳法就是从测试所暴露的错误出发,收集所有正确或不正确的数据,分析它们之间的关系,提出假想的错误原因,用这些数据来证明或反驳,从而查出错误所在。其步骤为:
|
|
|
|
.整理数据,找出规律,主要发现在什么条件下出现错误,什么条件下不出错。
|
|
|
.提出一个或多个错误原因,如果提不出来,则说明收集的数据不够,需要通过设计和执行附加的测试用例来得到。如果提出了多个错误原因,则应首先选择可能性最大的那个。
|
|
|
.用假设来解释所有的原始测试结果,如果能解释这一切,则假设将得以证实,也就将找出错误;否则,要么是假设不完备或不成立,要么有多个错误同时存在,需要重新分析,提出新的假设,直到发现错误为止。
|
|
|
|
根据测试结果,列出所有可能的错误原因。分析已有的数据,排除不可能和彼此矛盾的原因,对余下的原因选择可能性最大的,利用已有的数据完善该假设,使假设更具体。运用归纳法的第4步来证明假设的正确性。
|
|
|
以上这些方法均可辅以调试工具。随着测试技术和软件开发环境的发展,可以提供功能越来越强的自动测试和调试工具,支持断点设置、单步运行和各种跟踪技术,为软件的调试提供了很大的方便。但无论哪种工具都代替不了开发人员对整个文档和程序代码的仔细研究和认真审查所起的作用。
|
|
|