深入浅出学测试
作者:侠客人生
一:测试介绍
本章我们将重点讲解测试,在这一章里我们将学习为什么要测试,测试能到达到什么目的,测试有哪些,我们该如何测试,然后根据真实项目讲解一些常用测试。
软件测试是保证软件质量的重要手段。有些研究数据显示,国外软件开发机构40%的工作量花在软件测试上,软件测试费用占软件开发总费用的30%~50%(例如微软 、IBM...)。对于一些要求高可靠性、安全性的软件,测试费用可能相当于整个软件项目开发所有费用的3~5倍。要想成功的开发出高质量的软件产品,必须重视并加强软件的测试工作!
有些同学开始疑惑测试又不能保证我们的程序正确,花销又那么大为什么还要测试。再说了我们又不是微软、IBM何必呢,其实这就大错特错了,很多时候都是细节决定成败,你可能废了很大精力去开发一个项目,却因为缺少测试或没有认真测试而把“隐错(bug)”给放过了,最终导致项目失败是完全可能的,这不是我夸大奇谈,下面我也会给大家举一个真实案例的。测试可以增强我们对程序能够按照预期的结果运行的信心。找出“隐错(bug)”使我们的项目更加健康!
知己知彼才能百战不殆,学习测试之前学习一下测试的局限性是很重要的!测试不一定会使并发问题显露出来。(测试有可能无法发现与多个线程正并发地修改的一个小服务程序中的实例数据有关的问题)。测试也绝代替不了编程前的仔细思考;测试绝捕捉不了所有隐错。但是在这里,1针剂的防疫针确实比10针剂的特效药管用!
一个隐错出现的时间越长,纠正它的代价就会越高。有一项研究表明,最后纠正一个隐错的代价10倍于在该隐错被发现前经历的每一个阶段(需求、设计、实现或最后发布)纠正它所花费的代价。
二:测试定义
软件测试是使用人工操作或者软件自动运行的方式来检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别的过程。它是帮助识别开发完成(中间或最终的版本)的计算机软件(整体或部分)的正确度(correctness) 、完全度(completeness)和质量(quality)的软件过程;是SQA (software quality assurance)的重要子域。
软件测试的范畴很广,可以从是否关心软件内部结构和具体实现的角度去划分:白盒测试和黑盒测试。
A. 白盒测试
白盒测试也称结构测试或逻辑驱动测试,它是按照程序内部的结构测试程序,通过测试来检测产品内部动作是否按照设计规格说明书的规定正常进行,检验程序中的每条通路是否都能按预定要求正确工作。这一方法是把测试对象看作一个打开的盒子,测试人员依据程序内部逻辑结构相关信息,设计或选择
测试用例,对程序所有逻辑路径进行测试,通过在不同点检查程序的状态,确定
实际的状态是否与预期的状态一致。
B. 黑盒测试
黑盒测试也称功能测试,它是通过测试来检测每个功能是否都能正常使用。在测试中,把程序看作一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输
出信息。
也可以从是否执行程序的角度分为:静态测试和动态测试。
-
静态测试
静态方法是指不运行被测程序本身,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性。对需求规格说明书、软件设计说明书、源程序做结构分析、流程图分析、符号执行来找错。
-
动态测试
动态方法是指通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能,这种方法由三部分组成:构造测试实例、执行程序、分析程序的输出结果。
还可以从软件开发的过程按阶段划分有:单元测试、集成测试、确认测试、系统测试、验收测试。如图:
-
单元测试
单元测试是在软件开发过程中要进行的最低级别的测试活动,在单元测试活动中,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。单元测试不仅仅是作为无错编码一种辅助手段在一次性的开发过程中使用,单元测试必须是可重复的,无论是在软件修改,或是移植到新的运行环境的过程中。因此,所有的测试都必须在整个软件系统的生命周期中进行维护。
-
集成测试
在单元测试的基础上,将所有模块按照设计要求(如根据结构图〕组装成为子系统或系统,进行集成测试。实践表明,一些模块虽然能够单独地工作,但并不能保证连接起来也能正常的工作。程序在某些局部反映不出来的问题,在全局上很可能暴露出来,影响功能的实现。
-
确认测试
确认测试的目的是向未来的用户表明系统能够像预定要求那样工作。经集成测试后,已经按照设计把所有的模块组装成一个完整的软件系统,接口错误也已经基本排除了,接着就应该进一步验证软件的有效性,这就是确认测试的任务,即软件的功能和性能如同用户所合理期待的那样。
-
系统测试
将已经确认的软件、计算机硬件、外设、网络等其他元素结合在一起,进行信息系统的各种组装测试和确认测试,系统测试是针对整个产品系统进行的测试,目的是验证系统是否满足了需求规格的定义,找出与需求规格不符或与之矛盾的地方,从而提出更加完善的方案。
-
验收测试
验收测试是系统开发生命周期方法论的一个阶段,这时相关的用户和乙方或独立测试人员根据测试计划和结果对系统进行测试和接收。它让系统用户决定是否接收系统。它是一项确定产品是否能够满足合同或用户所规定需求的测试。
另外,根据测试目的的不同,还有回归测试、压力测试、性能测试等,分别为了检验修改或优化过程是否引发新的问题、软件所能达到处理能力和是否达到预期的处理能力等。
三:测试目的
1.发现一些可以通过测试避免的开发风险。
2.实施测试来降低所发现的风险。
3.确定测试何时可以结束。
4.在开发项目的过程中将测试看作是一个标准项目。
这是测试的目标, Glenford J.Myers曾对软件测试的目的提出过以下观点:
(1)测试是为了发现程序中的错误而执行程序的过程。
(2)好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案。
(3)成功的测试是发现了至今为止尚未发现的错误的测试。
(4)测试并不仅仅是为了找出错误。通过分析错误产生的原因和错误的发生趋势,可以帮助项目管理者发现当前软件开发过程中的缺陷,以便及时改进。
(5)这种分析也能帮助测试人员设计出有针对性的测试方法,改善测试的效率和有效性。
(6)没有发现错误的测试也是有价值的,完整的测试是评定软件质量的一种方法。
四:单元测试
单元测试
单元测试是在软件开发过程中要进行的最低级别的测试活动,在单元测试活动中,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。单元测试不仅仅是作为无错编码一种辅助手段在一次性的开发过程中使用,单元测试必须是可重复的,无论是在软件修改,或是移植到新的运行环境的过程中。因此,所有的测试都必须在整个软件系统的生命周期中进行维护。
-
单元测试的要点:
1、与其他部分相隔离
单元测试时,被测试代码依赖的代码,必须使用假的桩代码,因此,如果出问题的话,一定是被测试代码的问题。
2、单元测试必须是可重复的
随着项目的推移,被测试代码很可能被修改,并不是仅仅测试修改部分,还要运行其他单元测试,以保证修改的代码不会引入其他新的错误;因此,单元测试不能由手工进行,必须保证测试用例可以进行自我判断。
3、单元测试必须在整个软件系统的生命周期中维护
单元测试是其他阶段测试的基础,以集成测试为例,集成测试要把所有代码集合在一起,如果连单元测试都没通过,只能是给别人添麻烦。
4、单元测试—定义及其要点
重构(名词):对软件内部结构的一种调整,目的是在不改变「软件之可察行为」前提下,提高其可理解性,降低修改成本。
重构(动词):使用一系列重构准则(手法〕,在不改变「软件之可察行
为」前提下,调整其结构。
5、问题
•难以阅读的程序,难以修改。
•逻辑复杂(duplicated logic)的程序,难以修改。
•添加新行为时需要修改既有代码,难以修改。
•带复杂条件逻辑(complex conditional logic)的程序,难以修改。
我们可以看到,重构只是对软件内部调整,使得代码更具有可读性,可维护性,但是并不修改软件对外的行为。因此,在重构某个软件模块之前,我们需要写它的单元测试用例,并在重构后保证所有单元测试用例通过,才能保证不修改软件对外的行为。
-
单元测试—单元测试与重构
测试驱动开发--TDD(Test Driven Development)
测试驱动开发是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不只适用于XP(Extreme Programming),同样可以适用于其他开发方法和过程。TDD的基本思路就是通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析,设计,质量控制量化的过程。
-
nJUnit是什么
JUnit是由Erich Gamma和Kent Beck编写的一个回归测试框架(regression
testing framework)。Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。JUnit是一套框架,继承Test Case类,就可以用Junit进行自动测试。
JUnit核心概念
测试方法:测试模块中的一个功能;
夹具:夹具就是所有测试方法共有的初始条件。
夹具(fixture)是昂贵的,且应该对夹具进行重用,以运行不同的测试。
断言:JUnit为我们提供了一些辅助函数,它们用来帮助我们确定被测试的方法是否按照预期的效果正常工作。对测试至关重要,没有断言测试就没有意义。
测试用例:一个类,包含一组测试方法和夹具初始化方法。
测试套件:一组测试用例。