|
一、概述
信息技术的飞速发展,使软件产品应用到社会的各个领域,软件产品的质量自然成为人们共同关注的焦点。不论软件的生产者还是软件的使用者,均生存在竞争的环境中,软件开发商为了占有市场,必须把产品质量作为企业的重要目标之一,以免在激烈的竞争中被淘汰出局。用户为了保证自己业务的顺利完成,当然希望选用优质的软件。质量不佳的软件产品不仅会使开发商的维护费用和用户的使用成本大幅增加,还可能产生其他的责任风险,造成公司信誉下降,继而冲击股票市场。在一些关键应用 (如民航订票系统、银行结算系统、证券交易系统、自动飞行控制软件、军事防御和核电站安全控制系统等) 中使用质量有问题的软件,还可能造成灾难性的后果。
软件危机曾经是软件界甚至整个计算机界最热门的话题。为了解决这场危机,软件从业人员、专家和学者做出了大量的努力。现在人们已经逐步认识到所谓的软件危机实际上仅是一种状况,那就是软件中有错误,正是这些错误导致了软件开发在成本、进度和质量上的失控。有错是软件的属性,而且是无法改变的,因为软件是由人来完成的,所有由人做的工作都不会是完美无缺的。问题在于我们如何去避免错误的产生和消除已经产生的错误,使程序中的错误密度达到尽可能低的程度。
给软件带来错误的原因很多,具体地说,主要有如下几点:
①、交流不够、交流上有误解或者根本不进行交流
在应用应该做什么或不应该做什么的细节(应用的需求)不清晰的情况下进行开发。
②、软件复杂性
图形用户界面(GUI),客户/服务器结构,分布式应用,数据通信,超大型关系型数据库以及庞大的系统规模,使得软件及系统的复杂性呈指数增长,没有现代软件开发经验的人很难理解它。
③、程序设计错误
向所有的人一样,程序员也会出错。
④、需求变化
需求变化的影响是多方面的,客户可能不了解需求变化带来的影响,也可能知道但又不得不那么做。需求变化的后果可能是造成系统的重新设计,设计人员的日程的重新安排,已经完成的工作可能要重做或者完全抛弃,对其他项目产生影响,硬件需求可能要因此改变,等等。如果有许多小的改变或者一次大的变化,项目各部分之间已知或未知的依赖性可能会相互影响而导致更多问题的出现,需求改变带来的复杂性可能导致错误,还可能影响工程参与者的积极性。
⑤、时间压力
软件项目的日程表很难做到准确,很多时候需要预计和猜测。当最终期限迫近和关键时刻到来之际,错误也就跟着来了。
⑥、自负人更喜欢说:
'没问题'
'这事情很容易'
'几个小时我就能拿出来'
太多不切实际的‘没问题’,结果只能是引入错误。
⑦、代码文档贫乏
贫乏或者差劲的文档使得代码维护和修改变的异常艰辛,其结果是带来许多错误。事实上,在许多机构并不鼓励其程序员为代码编写文档,也不鼓励程序员将代码写得清晰和容易理解,相反他们认为少写文档可以更快的进行编码,无法理解的代码更易于工作的保密(“写得艰难必定读的痛苦”)。
⑧、软件开发工具
可视化工具,类库,编译器,脚本工具,等等,它们常常会将自身的错误带到应用软件中。就象我们所知道的,没有良好的工程化作为基础,使用面向对象的技术只会使项目变得更复杂。
为了更好地解决这些问题,软件界做出了各种各样的努力。
人们曾经认为更好的程序语言可以使我们摆脱这些困扰,这推动了程序设计语言的发展,更多的语言开始流行,为了使程序更易于理解开发了结构化程序设计语言,如PL/1,PASCAL等;为了解决实时多任务需求开发了结构化多任务程序设计语言,如Modula,Ada等;为了提高重用性开发了面向对象的程序设计语言,如Simlasa等;为了避免产生不正确的需求理解,开发形式化描述语言,如HAL/S等,这使得建立基于自然语言的描述成为可能,人们以形式化语言来描述需求;为了支持大型数据库应用,开发了可视化工具,如Visual Studio、Power Builder等。程序语言对提高软件生产效率起到了一定的积极作用,但它对整个软件质量尤其是可靠性的影响,与其他因素相比作用较小。
可能是因为程序语言基于严格的语法和语义规则,人们企图用形式化证明方法来证明程序的正确性。将程序当作数学对象来看待,从数学意义上证明程序是正确的是可能的。数学家对形式化证明方法最有兴趣,在论文上谈起来非常吸引人,但实际价值却非常有限,因为形式化证明方法只有在代码写出来之后才能使用,这显然太迟了,而且对于大的程序证明起来非常困难。
受到其他行业项目工程化的启发,软件工程学出现了,软件开发被视为一项工程,以工程化的方法来进行规划和管理软件的开发。
针对需求不确定的应用,可以使用渐进和迭代类的开发模型。还可以采用快速应用程序开发(RAD)和协同应用程序开发(JAD)技术,由软件开发者和用户代表共同参与开发软件规范。RAD和JAD的基本思路是开发者和用户共同设计系统中的屏幕,开发者迅速地把实现这些屏幕的最基本功能编写好,然后把它们交给用户看,然后用户和开发者回顾这些屏幕以确认它们达到了用户的要求,这个周期一直持续到系统的基本部分定义完毕。一旦设计被用户接受,开发者将完成完全实现屏幕需要的代码。RAD和传统软件开发项目之间的一个基本区别是:应用程序RAD系统是按阶段发布的。传统项目一般一次发布,也叫“big bang”。RAD方法使用高效开发工具,开发者能够非常迅速地设计出系统的基本屏幕,允许用户在开发周期中很早就能见识到系统将来看起来怎么样,避免了在传统开发项目中长篇大论并且枯燥难懂的说明。
IBM的Dr.Harlan Mills提出了净室过程。净室过程组合了形式化程序验证和统计过程控制(SPC)。在这种方法中,首先用正确性数学证明预防缺陷发生,然后用MTBF度量软件质量。净室过程是一种相当新的软件开发方法,它要求软件开发在管理方式和技术方法上作重大改变,特别是要求SPC应用到软件的知识,这影响了其被广泛的接受。
硬件成本持续降低,可支持CASE工具运行的新的强大的工作站和网络已经成为软件工程使用的工作平台,CASE工具可完成一些特定的软件开发过程。这些工具提供给软件设计者以图形方式描述软件设计的能力,这样就易于维护、易于交叉检查、易于理解。许多人(尤其是CASE工具供货商)相信CASE工具扮演了解决软件危机和拯救软件工业的角色,但事实上我们看到的情形却是许多公司花了大量的金钱买回的CASE工具但很少使用,原因在于这些工具执行的过程与机构的软件设计过程不相适用。
在可以借助许多新的技术和工具进行软件开发的今天,软件开发过程的成熟性问题开始引起人们的重视。这种产品一致性问题的主要症结在于管理,因此人们将目标转向了管理的改善,一些以改进软件开发过程为目标的活动已经展示出积极的结果。
以下是一些比较典型的文本。
SEI SW-CMM
ISO SPICE(Software Process Improvement and Capability dEtermination)
Bootstrap
ISO-9000-3
TickIT
Trillium
事实上,对于软件来讲,还没有象银弹那样的东西。不论采用什么技术和什么方法,软件中仍然会有错。采用新的语言、先进的开发方式、完善的开发过程,可以减少错误的引入,但是不可能完全杜绝软件中的错误,这些引入的错误需要测试来找出,软件中的错误密度也需要测试来进行估计。
测试是所有工程学科的基本组成单元,是软件开发的重要部分。自有程序设计的那天起测试就一直伴随着。统计表明,在典型的软件开发项目中,软件测试工作量往往占软件开发总工作量的40%以上。而在软件开发的总成本中,用在测试上的开销要占30%到50%。如果把维护阶段也考虑在内,讨论整个软件生存期时,测试的成本比例也许会有所降低,但实际上维护工作相当于二次开发,乃至多次开发,其中必定还包含有许多测试工作。因此,测试对于软件生产来说是必需的,问题是我们应该思考“采用什么方法、如何安排测试?”
二、软件测试的目的
软件测试的目的决定了如何去组织测试。如果测试的目的是为了尽可能多地找出错误,那么测试就应该直接针对软件比较复杂的部分或是以前出错比较多的位置。如果测试目的是为了给最终用户提供具有一定可信度的质量评价,那么测试就应该直接针对在实际应用中会经常用到的商业假设。
不同的机构会有不同的测试目的;相同的机构也可能有不同测试目的,可能是测试不同区域或是对同一区域的不同层次的测试。
在谈到软件测试时,许多人都引用Grenford J. Myers在《The Art of Software Testing》一书中的观点:
①、软件测试是为了发现错误而执行程序的过程;
②、测试是为了证明程序有错,而不是证明程序无错误。
③、一个好的测试用例是在于它能发现至今未发现的错误;
④、一个成功的测试是发现了至今未发现的错误的测试。
这种观点可以提醒人们测试要以查找错误为中心,而不是为了演示软件的正确功能。但是仅凭字面意思理解这一观点可能会产生误导,认为发现错误是软件测试的唯一目,查找不出错误的测试就是没有价值的,事实并非如此。
首先,测试并不仅仅是为了要找出错误。通过分析错误产生的原因和错误的分布特征,可以帮助项目管理者发现当前所采用的软件过程的缺陷,以便改进。同时,这种分析也能帮助我们设计出有针对性地检测方法,改善测试的有效性。
其次,没有发现错误的测试也是有价值的,完整的测试是评定测试质量的一种方法。详细而严谨的可靠性增长模型可以证明这一点。例如 Bev Littlewood发现一个经过测试而正常运行了n小时的系统有继续正常运行n小时的概率。
三、软件测试的基本方法
软件测试的方法和技术是多种多样的。
对于软件测试技术,可以从不同的角度加以分类:
从是否需要执行被测软件的角度,可分为静态测试和动态测试。
从测试是否针对系统的内部结构和具体实现算法的角度来看,可分为白盒测试和黑盒测试;
1、黑盒测试
黑盒测试也称功能测试或数据驱动测试,它是在已知产品所应具有的功能,通过测试来检测每个功能是否都能正常使用,在测试时,把程序看作一个不能打开的黑盆子,在完全不考虑程序内部结构和内部特性的情况下,测试者在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数锯而产生正确的输出信息,并且保持外部信息(如数据库或文件)的完整性。黑盒测试方法主要有等价类划分、边值分析、因—果图、错误推测等,主要用于软件确认测试。
“黑盒”法着眼于程序外部结构、不考虑内部逻辑结构、针对软件界面和软件功能进行测试。“黑盒”法是穷举输入测试,只有把所有可能的输入都作为测试情况使用,才能以这种方法查出程序中所有的错误。实际上测试情况有无穷多个,人们不仅要测试所有合法的输入,而且还要对那些不合法但是可能的输入进行测试。
2、白盒测试
白盒测试也称结构测试或逻辑驱动测试,它是知道产品内部工作过程,可通过测试来检测产品内部动作是否按照规格说明书的规定正常进行,按照程序内部的结构测试程序,检验程序中的每条通路是否都有能按预定要求正确工作,而不顾它的功能,白盒测试的主要方法有逻辑驱动、基路测试等,主要用于软件验证。
“白盒”法全面了解程序内部逻辑结构、对所有逻辑路径进行测试。“白盒”法是穷举路径测试。在使用这一方案时,测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。贯穿程序的独立路径数是天文数字。但即使每条路径都测试了仍然可能有错误。第一,穷举路径测试决不能查出程序违反了设计规范,即程序本身是个错误的程序。第二,穷举路径测试不可能查出程序中因遗漏路径而出错。第三,穷举路径测试可能发现不了一些与数据相关的错误。
3.ALAC(Act-like-a-customer)测试
ALAC测试是一种基于客户使用产品的知识开发出来的测试方法。ALAC测试是基于复杂的软件产品有许多错误的原则。最大的受益者是用户,缺陷查找和改正将针对哪些客户最容易遇到的错误。 |
|