《精通软件性能测试与LoadRunner最佳实战》—第1章1.4节软件测试的分类

  1. 云栖社区>
  2. 博客>
  3. 正文

《精通软件性能测试与LoadRunner最佳实战》—第1章1.4节软件测试的分类

异步社区 2017-05-02 11:23:00 浏览1136
展开阅读全文

本节书摘来自异步社区《精通软件性能测试与LoadRunner最佳实战》一书中的第1章1.4节软件测试的分类,作者于涌 , 王磊 , 曹向志 , 高楼 , 于跃,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.4 软件测试的分类
精通软件性能测试与LoadRunner最佳实战
软件测试按照测试阶段、是否运行程序、是否查看源代码以及其他方式,可以用图1-1所示来描述软件测试的各种分类。

黑盒测试、白盒测试与灰盒测试
1.黑盒测试
黑盒测试(Black-box Testing)是软件测试的主要方法之一,也可以称为功能测试、数据驱动测试或基于规格说明的测试。测试者不了解程序的内部情况,只知道程序的输入、输出和系统的功能,这是从用户的角度对程序进行的测试。软件的黑盒测试意味着测试要在软件的接口处进行。这种方法是把测试对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。

图1-1 测试的各种分类结构图

黑盒测试的随机性比较大,在大部分案例执行完成以后,大概能够测试40%的功能。据美国一个官方的数据说,20%的问题是在开发过程中发现的;80%的问题是在系统测试和集成测试过程中发现的,其中80%的比例我们还是需要再细分,20%的是使用的问题,20%是程序的问题,5%逻辑问题,剩下的都是莫名其妙的问题。这样的数据对测试的一个引导是:要想发现更多的问题,需要更多的思考,更多的组合。这样增加了很多工作量,人们在疲惫地执行着测试用例,渴望从中发现新的问题。

这样的用例设计思想使得我们在开发一个大型的产品或者延续性产品的时候,整个测试用例的延续性很差,重用性也很差。所以我们在这里需要纠正一个概念,黑盒测试不是简单地使用,用例设计也不是无谓地组合。

那么如何设计好的测试用例呢?如何在开发过程中很好地结合2/8原则呢?不可能出现一个完美无瑕的产品,但是作为软件工程师和软件测试工程师,肯定希望自己参与开发的产品稳定、易用并且能够受到用户的好评;希望自己参与的产品能够满足当前大多数人的需求,是否更合理呢?我相信通过软件工程师、测试工程师以及质量保证人员等的不断努力,我们的软件产品会让用户感到满意的。

2.白盒测试
白盒测试(White-box Testing)是另一种软件测试的主要方法,又称为结构测试、逻辑驱动测试或基于程序本身的测试,它着重于程序的内部结构及算法,通常不关心功能与性能指标。软件的白盒测试是对软件的过程性细节做细致的检查。这种方法是把测试对象看做一个打开的盒子,它允许白盒测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。通过在不同点检查程序状态,确定实际状态是否与预期的状态一致。

白盒测试是一种基于对源代码中的控制结构、处理过程等进行分析,检查程序内部处理是否正确、包括异常处理、语句结构、分支、循环结构等。很多控制软件,还要考虑有无冗余的代码,因为程序运行时,可能进入这些代码而无法再进行正常的执行(如进入了死循环状态,程序永远无法终止)。这种测试要求测试人员对程序的理解能力和编码能力很高,需要了解程序的构架、具体需求,以及一些编写程序的技巧,能够检查一些程序规范,以及指针、变量、数组越界等问题,使得问题在前期就暴露出来。

白盒测试一般是以单元或者模块为基础的。目前的做法是把它归结为开发的范畴。通常由资深的程序员、专职的白盒测试人员或利用专业的代码分析工具,如Boundchecker、JtestC++ Test等工具,这些工具可以帮助开发人员发现变量没有初始化、空指针、内存泄露以及代码不规范等问题。

白盒测试的主要方法包括以下几种。

语句覆盖:使得程序中每个语句至少都能被执行一次。
判定覆盖:使得程序中每个判定至少为真或假各一次。
条件覆盖:使得判定中的每个条件获得各种可能的结果。
判定/条件覆盖:同时满足判断覆盖和条件覆盖。
条件组合覆盖:使得每个判定中条件的各种可能组合都至少出现一次。
3.灰盒测试
灰盒测试(Gray-box Testing)是基于程序运行时刻的外部表现同时又结合程序内部逻辑结构来设计用例,执行程序并采集程序路径执行信息和外部用户接口结果的测试技术。这种测试技术介于白盒测试与黑盒测试之间,可以这样理解,灰盒测试关注输出对于输入的正确性,同时也关注内部表现。但这种关注不像白盒那样详细、完整,只是通过一些表征性的现象、事件、标志来判断内部的运行状态,有时候输出是正确的,但内部其实已经错误了,这种情况非常多,如果每次都通过白盒测试来操作,效率会很低,因此需要采取这样的一种灰盒的方法。

灰盒测试结合了白盒测试和黑盒测试的要素。它考虑了用户端、特定的系统知识和操作环境。

灰盒测试由方法和工具组成,这些方法和工具取材于应用程序的内部知识和与之交互的环境,能够用于黑盒测试以增强测试效率、错误发现和错误分析的效率。

灰盒测试涉及输入和输出,但使用关于代码和程序操作等通常在测试人员视野之外的信息设计测试。

静态测试与动态测试
静态测试和动态测试的概念在很多书中被提到,在这里也给大家介绍一下这两个概念。

1.静态测试
所谓静态测试(Static Testing),是指不运行被测试的软件,而只是静态地检查程序代码、界面或者文档中可能存在的错误的过程。

从概念中,大家不难发现静态测试主要包括三个方面内容的测试工作,即程序代码、界面和文档。

(1)程序代码测试:主要是程序员通过代码检查、代码评审等方式,对程序中是否存在编码不规范、代码编写是否和业务实现不一致,以及代码中是否有内存泄露、空指针等问题的测试。

(2)界面测试:主要是指测试人员从用户角度出发,根据公司的UI(User Interface,用户界面)设计规范检查被测试软件的界面是否符合用户的要求,在这里,非常赞同在开发软件产品之前,提供一个界面原型给用户参考,听取用户意见,而后不断完善原型,最后依照通过的原型实现软件的做法。

(3)文档测试:主要是测试人员对需求规格说明书、用户手册是否符合用户要求的检查过程。

为了能够说明静态测试是如果进行的,我们现在仅以对程序代码测试为例,给大家介绍一下。

首先,请大家看一段由C语言实现的小程序,代码如下所示:

void msg(char *explanation)
{
    char p1;
    p1 = malloc(100);
   .(void) sprintf(p1,"The error occurred because of '%s'.",explanation);
}

不知道您看到问题了吗?如果您对C语言有一定了解的话,应该清楚内存申请完成以后,在完成任务后,必须要把申请的内存回收,否则就会造成内存的泄露发生。从上面的代码我们不难发现,每次应用msg()函数都会泄露100字节的内存。在内存充裕的情况下,一二次泄露是微不足道的,但是连续操作数小时后,特别是在多用户并发的情况下,持续运行一段时间之后,则即使如此小的泄露也会削弱应用程序的处理能力,最后的结果必将是内存资源耗尽!

在实际的C、C++编程中,您在代码中对内存malloc()(分配)以后,在完成任务以后一定要记得把那部分申请的内存通过free()给释放掉,当然您还需要注意应用文件操作的时候,也要把文件给关闭,建立一个连接以后也要把连接给关掉等问题,上面提及的情况,如果没有及时关闭申请的资源同样是会出现内存泄露情况的。

除了上面说到的代码方面的问题以外,文档中缺少注释信息也是一个问题。大家知道一个软件在编写过程中,通常都是多个人相互协作,每个人编写一部分功能模块,每个人可能都非常清楚自己编写模块的内容,但是有时候难免会碰到您去修改别人代码的时候(如某个研发人员离职了,您需要维护他编写的那部分代码),这时如果没有注释信息,您可能理解几十万、上百万行的代码是极其困难的,但是在有注释的情况下,您就能很快了解作者的意图,方便后期代码的维护。

2.动态测试
与静态测试相对应的就是动态测试。所谓动态测试(Dynamic Testing),是指实际运行被测试的软件,输入相应的测试数据,检查实际输出结果是否和预期结果相一致的过程。从静态测试和动态测试的概念我们不难发现,静态测试和动态测试的唯一区别就是是否运行程序。

为了能够说明动态测试是如何进行的,我们现在也举一个具体的实例,给大家介绍一下。以Windows自带的计算器程序为例,如我们输入“5+50=”,在设计用例的时候,预期结果应该为“,如果结果不等于“则说明程序是错误的,请大家参见图1-2。


b127a31677da0638fa31bda33e30e13fb3f47084

单元测试、集成测试、系统测试与验收测试
1.单元测试
单元测试是测试过程中的最小粒度,它在执行的过程中紧密地依照程序框架对产品的函数和模块进行测试,包含入口和出口的参数,输入和输出信息,错误处理信息,部分边界数值测试。

这个部分的测试工作,目前,在国内大多数情况下是由开发人员进行的。我相信未来的发展应该是测试工程师来做这个事情。这和目前国内软件测试刚刚起步的阶段是有密切关系的,随着软件行业的蓬勃发展,越来越多的软件企业已经意识到白盒测试的重要程度,特别是在军工、航天以及一些对人身、财产安全影响重大的项目中,白盒测试的重要意义不言而喻。当然,这样意义重大的事情,对白盒测试人员的综合能力也提出了更高的要求,从业人员必须对需求、系统框架、代码以及测试技术等方面都要有深刻的理解,这样才能发现问题。

还有一种大家坐在一起讨论评审的方法,就是当一个模块给某个开发工程师以后,需要他给大家讲解,他要完成这个模块或者函数的整体流程和思路,进行统一评审,使得问题能够暴露得更充分些,这样做的目的有以下几个原因。第一,使得大家对设计者思路明晰的理解,以便以后调用或者配合的时候能够真切地提出需求或者相对完美配合。第二,在评审的过程中,如果发现问题,那么大家可能没有遇见过,这样就会更加提高警惕,如果遇见过,就会回想当时自己怎么解决的或者规避的,使得大家能够避免错误的发生,减少解决问题的周期。第三,可以对平常所犯错误进行一个积累,这是生动的教科书,可以使得新的人员在上手的时候就借鉴前人的一些经验,遇到这样的问题以后,可以给他们一个解决问题的方法或者方向。

上面给大家介绍了两种方法,第一种就是通过在开发的过程中进行测试,由开发(白盒测试)工程师写测试代码,对所编写的函数或者模块进行测试;第二种就是通过代码互评发现问题,将问题进行积累,形成知识积累库,以便使得其他开发人员在遇到同样问题时不至于再犯错误。

单元测试非常重要,因为它影响的范围和宽度比较大,也许由于一个函数或者参数问题,造成后面暴露出很多表象问题出现。而且如果单元测试做不好,使得集成测试或者后面系统测试的压力很大,这样项目的费用和进度可能就会受到影响。

对单元测试,有很多工具可以应用,现在主流是Xunit系列(即针对Java的单元测试主要用Junit,.Net则有Nunit,Delphi有Dunit等工具),当然,除了Xunit系列的单元测试工具,也有其他的工具,如Cppunit、Comunit、ParaSoft的Jtest等。测试人员应该在单元测试工作中不断积累工作经验,不断加强、改进工作方法,增强单元测试力度。

保证单元测试顺利进行,需要渗透软件工程的很多思想,把CMM和跟踪机制建立起来,把问题进行分类与跟踪,如果把软件环节整个活动都渗透了,那么产品质量的意识自然就增强了。

单元测试做什么呢?

单元测试主要任务包括:

① 模块接口测试;

② 模块局部数据结构测试;

③ 模块中所有独立执行路径测试;

④ 模块的各条错误处理路径测试;

⑤ 模块边界条件测试。

(1)模块接口测试。

模块接口测试是单元测试的基础,主要检查数据能否正确地通过模块。只有在数据能正确流入、流出模块的前提下,其他测试才有意义。

测试接口正确与否应该考虑下列因素:

① 输入的实际参数与形式参数的个数是否相同;

② 输入的实际参数与形式参数的属性是否匹配;

③ 输入的实际参数与形式参数的量纲是否一致;

④ 调用其他模块时所给实际参数的个数是否与被调模块的形参个数相同;

⑤ 调用其他模块时所给实际参数的属性是否与被调模块的形参属性匹配;

⑥ 调用其他模块时所给实际参数的量纲是否与被调模块的形参量纲一致;

⑦ 调用预定义函数时所用参数的个数、属性和次序是否正确;

⑧ 是否存在与当前入口点无关的参数引用;

⑨ 是否修改了只读型参数;

对全程变量的定义各模块是否一致;

是否把某些约束作为参数传递。

如果模块内包括外部输入输出,还应该考虑下列因素:

① 文件属性是否正确;

② 打开或关闭语句是否正确;

③ 格式说明与输入输出语句是否匹配;

④ 缓冲区大小与记录长度是否匹配;

⑤ 文件使用前是否已经打开;

⑥ 是否处理了文件尾;

⑦ 是否处理了输入/输出错误;

⑧ 输出信息中是否有文字性错误。

(2)局部数据结构测试。

检查局部数据结构是为了保证临时存储在模块内的数据在程序执行过程中完整、正确。局部数据结构往往是错误的根源,应仔细设计测试用例,力求发现下面几类错误:

① 不合适或不相容的类型说明;

② 变量无初值;

③ 变量初始化或默认值有错;

④ 不正确的变量名(拼错或不正确地截断);

⑤ 出现上溢、下溢和地址异常;

⑥ 除了局部数据结构外,如果可能,单元测试时还应该查清全局数据(如Fortran的公用区)对模块的影响。

(3)独立执行路径测试。

在模块中应对每一条独立执行路径进行测试,单元测试的基本任务是保证模块中每条语句至少执行一次。此时设计测试用例是为了发现因错误计算、不正确的比较和不适当的控制流造成的错误,其中基本路径测试和循环测试是最常用且最有效的测试技术,常见的错误包括:

① 误解或用错算符优先级;

② 混合类型运算;

③ 变量初值错;

④ 精度不够;

⑤ 表达式符号错。

比较判断与控制流常常紧密相关,测试用例还应致力于发现下列错误:

① 不同数据类型的对象之间进行比较;

② 错误地使用逻辑运算符或优先级;

③ 因计算机表示的局限性,期望理论上相等而实际上不相等的两个量相等;

④ 比较运算或变量出错;

⑤ 循环终止条件或不可能出现;

⑥ 错误地修改了循环变量。

(4)错误处理路径测试。

一个好的设计应能预见各种出错情况,并对这些出错的情况预设各种出错处理路径,出错处理路径同样需要认真测试,在测试时应着重检查下列问题:

① 输出的出错信息难以理解;

② 记录的错误与实际遇到的错误不相符;

③ 在程序自定义的出错处理段运行之前,系统已介入进行处理;

④ 异常处理不当,导致数据不一致等情况发生;

⑤ 错误陈述中未能提供足够的定位出错信息。

(5)边界条件测试。

边界条件测试是单元测试中重要的一项任务。众所周知,软件经常在边界上失效,采用边界值分析技术,针对边界值及其边界值的左、右设计测试用例,很有可能发现新的错误。

(6)单元测试方法。

一般认为单元测试应紧接在编码之后,当源程序编制完成并通过复审和编译检查,便可开始单元测试。测试用例的设计应与复审工作相结合,根据设计信息选取测试数据,将增大发现上述各类错误的可能性。在确定测试用例的同时,应给出期望结果。

由于被测试的模块往往不是独立的程序,它处于整个软件结构的某一层上,被其他模块调用或调用其他模块,其本身不能单独运行,因此在单元测试时,应为测试模块开发一个驱动(Driver)模块和(或)若干个桩(Stub)模块,图1-3显示了一般单元测试的环境。


df9a52f39a30c1a357da75dda94b53d497ce7843

驱动模块的作用是用来模拟被测模块的上级调用模块,功能要比真正的上级模块简单得多,它接收测试数据并将这些数据传递到被测试模块,被测试模块被调用后,可以打印“进入-退出”消息。桩模块用来代替被测模块所调用的模块,用以返回被测模块所需的信息。

驱动模块和桩模块是测试使用的软件,而不是软件产品的组成部分,其编写需要一定的开发费用。若驱动和桩模块比较简单,实际开发成本相对低些。遗憾的是,仅用简单的驱动模块和桩模块不能完成某些模块的测试任务,这些模块的单元测试只能采用后面讨论的集成测试方法。

2.集成测试
时常有这样的情况发生,每个模块都能单独工作,但这些模块集成在一起之后却不能正常工作,其主要原因是模块相互调用时接口会引入许多新问题。例如,数据经过接口可能丢失;一个模块对另一模块可能造成不应有的影响;几个子功能组合起来不能实现主功能;误差不断积累,最后,则达到不可接受的程度;全局数据结构出现错误等。集成测试是组装软件的系统测试技术,按设计要求把通过单元测试的各个模块组装在一起之后,进行综合测试以便发现与接口有关的各种错误。

集成测试包括两种不同方法:非增量式集成和增量式集成。研发人员习惯于把所有模块按设计要求一次全部组装起来,然后进行整体测试,这称为非增量式集成。这种方法容易出现混乱,因为测试时可能发现一大堆错误,为每个错误定位和纠正非常困难,并且在改正一个错误的同时又可能引入新的错误,新旧错误混杂,更难断定出错的原因和位置。与之相反的是增量式集成方法,程序一段一段地扩展,测试的范围一步一步地加强,错误易于定位和纠正,界面的测试也可做到完全彻底。

(1)增量式集成方法的两种类型。

增量式集成方法主要包括自顶向下集成和自底向上集成两种类型。

自顶向下增量式测试表示逐步集成和逐步测试是按结构图自上而下进行的。即模块集成的顺序是首先集成主控模块(主程序),然后按照软件控制层次结构向下进行集成。

自底向上增量式测试是从最底层的模块开始,按结构图自下而上逐步进行集成和测试。

集成测试主要测试软件的结构问题,因为测试建立在模块的接口上,所以多为黑盒测试,适当辅以白盒测试。

执行集成测试应遵循下面的方法:

① 确认组成一个完整系统的模块之间的关系;

② 评审模块之间的交互和通信需求,确认出模块间的接口;

③ 使用上述信息产生一套测试用例;

④ 采用增量式测试,依次将模块加入到系统,并测试新合并后的系统,这个过程以一个逻辑/功能顺序重复进行,直至所有模块被功能集成进来形成完整的系统为止。

此外,在测试过程中尤其要注意关键模块,所谓关键模块一般都具有下述一个或多个特征:

① 对应几条需求;

② 具有高层控制功能;

③ 复杂,易出错;

④ 有特殊的性能要求。

因为集成测试的主要目的是验证组成软件系统的各模块的接口和交互作用,因此集成测试对数据的要求无论从难度和内容来说一般不是很高。集成测试一般也不使用真实数据,测试人员可以使用手工制作一部分代表性的测试数据。在创建测试数据时,应保证数据充分测试软件系统的边界条件。

在单元测试时,根据需要生成了一些测试数据,在集成测试时可适当地重用这些数据,这样可节省时间和人力。

(2)集成测试遵循的原则。

集成测试很不好把握,应针对总体设计尽早开始筹划。为了做好集成测试,需要遵循以下原则:

① 所有公共接口都要被测试到;

② 关键模块必须进行充分的测试;

③ 集成测试应当按一定的层次进行;

④ 集成测试的策略选择应当综合考虑质量、成本和进度之间的关系;

⑤ 集成测试应当尽早开始,并以总体设计为基础;

⑥ 在模块与接口的划分上,测试人员应当和开发人员进行充分的沟通;

⑦ 当接口发生修改时,涉及的相关接口必须进行再测试;

⑧ 测试执行结果应当如实记录。

3.系统测试
集成测试通过以后,软件已经组装成一个完整的软件包,这时就要进行系统测试。系统测试完全采用黑盒测试技术,因为这时已不需要考虑组件模块的实现细节,而主要是根据需求分析时确定的标准检验软件是否满足功能、性能等方面的要求。系统测试所用的数据必须尽可能地像真实数据一样准确和有代表性,也必须和真实数据的大小和复杂性相当。满足上述测试数据需求的一个方法是使用真实数据。在不使用真实数据的情况下应该考虑使用真实数据的一个复制。复制数据的质量、精度和数据量必须尽可能地代表真实的数据。当使用真实数据或使用真实数据的复制时,仍然有必要引入一些手工数据。在创建手工数据时,测试人员必须采用正规的设计技术,使得提供的数据真正代表正规和异常的测试数据,确保软件系统能充分地测试。

系统测试需要有广泛的知识面,对测试工程师的要求需要了解和掌握很多方面的知识,需要了解问题可能出现的原因,已经出现这个问题可能是由于什么原因造成的,以便我们能够及时地补充测试用例,保证或者降低产品发行后的风险。

系统测试阶段是测试发现问题的主要阶段,系统测试重复的工作量比较大。如果是一个大型的项目,涉及的内容相对比较多。测试本身是一件重复性的工作,很多时候我们要部署同样的测试环境,测试同样的模块功能,反反复复地输入相同的测试数据,这是十分枯燥和乏味的工作。很容易让人厌烦,所以如果能够将部分有规律的重复性工作使用自动化测试工具来进行,会使得我们的工作量减少,提高工作效率。

4.验收测试
系统测试完成之后,软件已完全组装起来,接口方面的错误也已排除,这时可以开始对软件进行最后的确认测试。确认测试主要检查软件能否按合同要求进行工作,即是否满足软件需求规格说明书中的要求。

软件确认要通过一系列黑盒测试。确认测试同样需要制订测试计划和过程,测试计划应规定测试的种类和测试进度,测试过程则定义一些特殊的测试用例,旨在说明软件与需求是否一致。无论是计划还是过程,都应该着重考虑软件是否满足合同规定的所有功能和性能,文档资料是否完整、准确,人机界面和其他方面(例如,可移植性、兼容性、错误恢复能力和可维护性等)是否满足客户要求。

确认测试的结果有两种可能:一种是功能和性能指标满足软件需求说明的要求,用户可以接受;另一种是软件不满足软件需求说明的要求,用户无法接受。项目进行到这个阶段才发现严重错误和偏差一般很难在预定的工期内改正,因此必须与用户协商,寻求一个妥善解决问题的方法。

事实上,软件开发人员不可能完全预见用户实际使用程序的情况。例如,用户可能错误地理解命令,或提供一些奇怪的数据组合,也可能对系统给出的提示信息迷惑不解等。因此,软件是否真正满足最终用户的要求,应由用户进行一系列“验收测试”。验收测试既可以是非正式的测试,也可以有计划有系统的测试。有时,验收测试长达数周甚至数月,不断暴露错误,导致开发延期。一个软件产品可能拥有众多用户,不可能由每个用户验收,此时多采用称为、 测试的过程,以期发现那些似乎只有最终用户才能发现的问题。

测试是指软件开发公司组织内部人员模拟各类用户行为对即将面市软件产品(称为版本)进行测试,试图发现错误并修正。测试的关键在于尽可能地模拟实际运行环境和用户对软件产品的操作,并尽最大努力涵盖所有可能的用户操作方式。经过测试调整的软件产品称为 版本。紧随其后的 测试是指软件开发公司组织各方面的典型用户(如放到互联网上供用户免费下载,并可以试用一定期限,或者以光盘等形式免费发放给部分期待试用的未来潜在客户群用户,也可以使用一定的期限,这个期限通常可能是几天也可能是几个月)在日常工作中实际使用__版本,并要求用户报告异常情况、提出改进意见,然后软件开发公司再对 版本进行改错和完善。

其他测试
1.回归测试
无论是进行黑盒测试还是白盒测试都会涉及回归测试,那么什么是回归测试呢?回归测试是指对软件新的版本测试时,重复执行上一个版本测试时使用的测试用例。

在软件生命周期中的任何一个阶段,只要软件发生了改变,就可能给该软件带来问题。软件的改变可能是源于发现了错误并做了修改,也有可能是因为在集成或维护阶段加入了新的模块。当软件中所含错误被发现时,如果错误跟踪与管理系统不够完善,就可能会遗漏对这些错误的修改;而开发者对错误理解得不够透彻,也可能导致所做的修改只修正了错误的外在表现,而没有修复错误本身,从而造成修改失败;修改还有可能产生副作用从而导致软件未被修改的部分产生新的问题,使本来工作正常的功能产生错误。同样,在有新代码加入软件的时候,除了新加入的代码中有可能含有错误外,新代码还有可能对原有的代码带来影响。因此,每当软件发生变化时,我们就必须重新测试现有的功能,以便确定修改是否达到了预期的目的,检查修改是否损害了原有的正常功能。同时,还需要补充新的测试用例来测试新的或被修改了的功能。为了验证修改的正确性及其影响就需要进行回归测试。

回归测试在软件生命周期中扮演着重要的角色,因忽视回归测试而造成严重后果的例子不计其数,导致阿里亚娜V形火箭发射失败的软件缺陷就是由于复用的代码没有经过充分的回归测试造成的。我们平时也经常会听到一些客户的抱怨,说:“以前应用没有问题的功能,现在怎么有问题了?”这些通常是因为鉴于商机、实施等部门对软件开发周期的限制因素,开发人员对软件系统增加或者改动部分系统功能,由于时间紧迫的原因,明确与测试部门说明只进行新增或者变更的模块进行测试,而对其他未修改的模块不需要进行测试或者干脆说不需要测试,由于软件系统各个模块之间存在着或多或少的联系,很有可能因为新增加的功能变化,而引起其他模块不能进行正常的工作,所以只测试新增模块,不对系统进行完整功能的测试,导致以前应用没有问题的功能,现在出现了问题。

2.冒烟测试
冒烟测试的名称可以理解为该种测试耗时短,仅用一袋烟功夫足够了。也有人认为是形象地类比新电路板基本功能检查。任何新电路板焊好后,先通电检查,如果存在设计缺陷,电路板可能会短路,板子冒烟了。

冒烟测试的对象是每一个新编译的需要正式测试的软件版本,目的是确认软件基本功能正常,可以进行后续的正式测试工作。冒烟测试的执行者是版本编译人员或其他研发人员。

在一般软件公司,软件在编写过程中,内部需要编译多个版本,但是只有有限的几个版本需要执行正式测试(根据项目开发计划),这些需要执行的中间测试版本,在刚刚编译出来后,软件编译人员需要进行常规的测试,例如,是否可以正确安装/卸载,主要功能是否实现了,数据严重丢失等。如果通过了该测试,则可以根据正式测试文档进行正式测试,否则,就需要重新编译版本,再次执行版本构建、打包和测试,直到成功为止。冒烟测试的好处是可以节省大量的时间成本和人力、物力成本,避免由于打包失误、功能严重缺失、硬件部件损坏导致软件运行失败等严重问题而引起大量测试人员从事没有意义的测试劳动。

3.随机测试
随机测试是这样一种测试,在测试中,测试数据是随机产生的。例如,我们测试一个系统的姓名字段,姓名长度可达12个字符,那么可能随机输入以下12个字符:“ay5%,,i567aj”,显然,没有人叫这样一个名字,并且可能该字段不允许出现%等一些字符,所以对随机产生的输入集合我们要进行提炼,省略掉一些不符合要求的测试集。并且这样随机产生的用例可能还只覆盖了一部分等价类,大量的情况无法覆盖到。这样的测试有时又叫猴子测试(Monkey Testing)。

随机测试有这样一些缺点:

(1)测试往往不太真实;

(2)不能达到一定的覆盖率;

(3)许多测试都是冗余的;

(4)需要使用同样的随机数种子才能重建测试。

这种随机测试在很多时候没有多大的用处,往往被用来作为“防崩溃”的手段,或者被用来验证系统在遭受不利影响时是否能保持正常。作者觉得随机测试在面向网络,特别是因特网、不确定群体时还是非常有用的,因为不仅仅是真正想使用系统的用户,也有很多乐于攻击系统和制造垃圾数据的人,这是考察一个系统健壮性、防止生成大量垃圾数据的情况时非常有用的,有很多系统就因为前期不注重控制垃圾数据的输入,导致数据量急速增长,后来又不得不做一个数据校验程序来限制或删除垃圾数据,无形中又增加了工作量。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

网友评论

登录后评论
0/500
评论
异步社区
+ 关注