软件测试的艺术(原书第3版)
上QQ阅读APP看书,第一时间看更新

第1章 一次自评价测试

自本书30年前首次出版以来,软件测试变得比以前容易得多,也困难得多。

软件测试何以变得更困难?原因在于大量的编程语言、操作系统以及硬件平台的涌现。在20世纪70年代只有相当少的人使用计算机,而在今天几乎人人离不开计算机。而今天计算机不仅仅是指摆在你书桌上的计算机了,几乎所有我们所接触和使用的电子设备都内置了一个“计算机”或者计算芯片,以及运行在其上的软件系统。不妨回想一下在今天的社会中还在使用哪些不需要软件驱动的设备,没错,锤子和手推车是,但是这些工具也大量使用在由软件控制和操作的车间中。软件的普遍应用提升了测试的意义。今天的设备已经千百倍强于它们的“前辈”,今天的“计算机”这个概念也变得越来越广泛和越来越难准确地定义。数字电视、电话、游戏产品、汽车等都有一颗计算机的“心”以及运行其中的软件,以至于在某些情况下它们自己本身也能够被看做是一台特别的计算机。

因此,现在的软件会潜在地影响到数以百万计的人,使他们更高效地完成工作,反之也会给他们带来数不清的麻烦,导致工作或事业的损失。这并不是说今天的软件比本书第1版发行时更重要,但可以肯定地说,今天的计算机(以及驱动它的软件)无疑已影响到了更多的人、更多的行业。

就某些方面而言,软件测试变得更容易了,因为大量的软件和操作系统比以往更加复杂,内部提供了很多已充分测试过的例程供应用程序集成,无须程序员从头进行设计。例如,图形用户界面(GUI)可以从开发语言的类库中建立起来,同时,由于它们是经过充分调试和测试的预编程对象,将其作为自定义应用程序的组成部分进行测试的要求就减少了许多。

另外,尽管市场上的测试书籍越来越多,甚至有过剩之嫌,似乎依旧有很多开发人员对全面的测试并不那么欢迎。引入更优秀的开发工具、使用已经通过测试的GUI(图形界面控件)控件、紧张的交付日期以及高度集成的便利开发环境会让测试变得仅仅是让那些最基本的测试用例走走过场罢了。影响不大的bug也许只不过会让最终用户觉得使用不方便而已,然而严重的bug则可能造成经济损失甚至是人身伤害。本书所阐述的方法旨在帮助设计人员、开发工程师以及项目经理更好地理解全面综合测试的意义所在,并提供行之有效的指南以帮助达成测试的目标。

所谓软件测试,就是一个过程或一系列过程,用来确认计算机代码完成了其应该完成的功能,不执行其不该有的操作。软件应当是可预测且稳定的,不会给用户带来意外惊奇。在本书中,我们将讨论多种方法来达到这个目标。

好了,在开始阅读本书之前,我们想让读者做一个小测验。我们要求设计一组测试用例(特定的数据集合),适当地测试一个相当简单的程序。为此要为该程序建立一组测试数据,程序须对数据进行正确处理以证明自身的成功。下面是对该程序的描述:

这个程序从一个输入对话框中读取三个整数值,这三个整数值代表了三角形三条边的长度。程序显示提示信息,指出该三角形是何种三角形:不规则三角形、等腰三角形还是等边三角形。

注意,所谓不规则三角形是指三角形中任意两条边不相等,等腰三角形是指有两条边相等,而等边三角形则是指三条边相等。另外,等腰三角形等边的对角也相等(即任意三角形等边的对角也相等),等边三角形的所有内角都相等。

用你的测试用例集回答下列问题,借以对其进行评价。对每个回答“是”的答案,可以得1分:

1.是否有这样的测试用例,代表了一个有效的不规则三角形?(注意,如1、2、3和2、5、10这样的测试用例并不能确保“是”的答案,因为具备这样边长的三角形不存在。)

2.是否有这样的测试用例,代表一个有效的等边三角形?

3.是否有这样的测试用例,代表一个有效的等腰三角形?(注意,如2、2、4的测试用例无效,因为这不是一个有效的三角形。)

4.是否至少有三个这样的测试用例,代表有效的等腰三角形,从而可以测试到两等边的所有三种可能情况(如3、3、4;3、4、3;4、3、3)?

5.是否有这样的测试用例,某边的长度等于0?

6.是否有这样的测试用例,某边的长度为负数?

7.是否有这样的测试用例,三个整数皆大于0,其中两个整数之和等于第三个?(也就是说,如果程序判断1、2、3表示一个不规则三角形,它可能就包含一个缺陷。)

8.是否至少有三个第7类的测试用例,列举了一边等于另外两边之和的全部可能情况(如1、2、3;1、3、2;3、1、2)?

9.是否有这样的测试用例,三个整数皆大于0,其中两个整数之和小于第三个整数(如1、2、4;12、15、30)?

10.是否至少有三个第9类的测试用例,列举了一边大于另外两边之和的全部可能情况(如1、2、4;1、4、2;4、1、2)?

11.是否有这样的测试用例,三边长度皆为0(0,0,0)?

12.是否至少有一个这样的测试用例,输入的边长为非整数值(如2.5、3.5、5.5)?

13.是否至少有一个这样的测试用例,输入的边长个数不对(如仅输入了两个而不是三个整数)?

14.对于每一个测试用例,除了定义输入值之外,是否定义了程序针对该输入值的预期输出值?

当然,测试用例集即使满足了上述条件,也不能确保能查找出所有可能的错误。但是,由于问题1至问题13代表了该程序不同版本中已经实际出现的错误,对该程序进行的充分测试至少应该能够暴露这些错误。

开始关注自己的得分之前,请考虑以下情况:以我们的经验来看,高水平的专业程序员平均得分仅7.8(满分14)。如果读者的得分更高,那么祝贺你。如果没有那么高,我们将尽力帮助你。

这个测验说明,即使测试这样一个小的程序,也不是件容易的事。因此,想象一下测试一个十万行代码的空中交通管制系统、一个编译器,甚至一个普通的工资管理程序的难度。随着面向对象编程语言(如Java、C++)的出现,测试也变得更加困难。举例来说,为测试这些语言开发出来的应用程序,测试用例必须要找出与对象实例或内存管理有关的错误。

从上面这个例子来看,完全地测试一个复杂的、实际运行的程序似乎是不太可能的。情况并非如此!尽管充分测试的难度令人望而生畏,但这是软件开发中一项非常必需的任务,也是可以实现的一部分工作,通过本书我们可以认识到这一点。