第2章 软件测试策略与过程
约47%的软件故障是由用户发现的,并只与系统当中4%的程序模块有关。
软件测试充分性准则:
(1) 对任何软件系统都存在有限的充分测试集合。
(2) 如果一个软件系统在一个测试数据(测试用例)集合上的测试是充分的,那么再次测试一些测试数据也应该是充分的,这一特性称作测试的单调性。
(3) 即使对软件所有的组成成分都进行了充分的测试,也并不能标明整体软件系统的测试已经充分了,这一特性称作测试的非复合性。
(4) 即使对软件系统整体的测试是充分的,也并不能证明软件系统中各组成成分都已经充分地得到了测试,这个特性称作测试的非分解性。
(5) 软件测试的充分性应与软件的需求和软件的实现都相关。
(6) 软件越复杂,需要的测试数据(测试用例)就越多,这一特性称作测试的复杂性。
(7) 测试得越多,进一步测试所能获得的充分性增长就越少,这一特性称作测试的回报递减率。
静态测试属于早期测试。静态测试包括过程步骤和实现技术两部分。静态测试的过程和步骤是需求分析、概要设计、详细设计和计划执行四部分;实现技术主要包括代码检查、静态结构分析、代码质量度量等。
静态结构分析主要是以图形的方式表现程序的内部结构。
代码质量度量。针对软件的可维护性,目前在测试工程中主要存在三种度量的参数:Line复杂度、Halstead复杂度和McCabe复杂度。其中Line复杂度以代码的行数作为计算的基准;Halstead复杂度是以程序中使用到的运算符与运算元数量作为计数目标(直接测量指标),然后可以据此计算出程序的容量、工作量等;McCabe复杂度一般称为圈复杂度(Cyclomatic Complexity),它是将软件程序的流程图结构转化为有向图结构,然后以图论的方式来衡量软件的复杂度度量。McCabe完整的复杂度包括了圈复杂度、基本复杂度、模块设计复杂度和集成的复杂度。
动态测试具体内容包括功能确认与接口测试、覆盖率分析、性能分析及内存分析等。
黑盒测试
黑盒测试有时也称为功能测试、数据驱动测试和基于规格说明的测试。它是一种从用户观点(依据需求而确定的)出发的测试。黑盒测试一般被用来确认软件功能的正确性和可操作性。
黑盒测试有三个显著的特点:①黑盒测试与软件的具体实现过程无关,在软件实现的过程和方法发生变化时,测试用例仍然可以使用;②黑盒测试可用于软件测试的各个阶段,如单元测试、系统性测试等;③黑盒测试用例的设计可以和软件实现同时进行,这样能减少软件开发进程时间和成本,保证质量。
黑盒测试的具体技术方法主要包括边界值分析法、等价类划分法、比较测试法、因果图法、决策表法等。
黑盒测试属于穷举输入测试方法。
白盒测试
白盒测试也成为结构测试、逻辑驱动测试或基于程序的测试。它一般用来分析程序的内部结构,测试依赖于对程序细节的严格检查。白盒测试针对软件(程序)的特定条件和循环来设计测试用例,对程序的逻辑路径进行遍历性和响应性测试。白盒测试的焦点集中在如何根据其内部结构去设计测试用例并执行。
白盒测试法事穷举路径的测试。
即使每条路径都测试了仍可能存在错误。第一,穷举路径测试决不能查处程序违反了设计规范;第二,穷举路径测试不可能查处程序中因遗漏路径而出错;第三,穷举路径测试可能发现不了一些与数据相关的错误。
通常的程序结构覆盖有下列5种:
(1) 语句覆盖:最弱的逻辑覆盖准则,要求设计若干测试用例,使被测程序的每个语句都至少被执行一次。
(2) 判断覆盖:判定覆盖或分支覆盖要求设计若干测试用例,使被测程序的每个判定的真、假分支都至少被执行一次。
(3) 条件覆盖:当判定含有多个条件时,可以要求设计若干个测试用例,使被测程序的每个条件的真、假分支都至少被执行一次,即条件覆盖。在考虑对程序路径进行全面检验时,即可使用条件覆盖准则。
(4) 判断/条件覆盖:根据判定覆盖与条件覆盖的混合原则而进行测试用例设计,进行覆盖。
(5) 路径覆盖:对程序所有路径的各种覆盖。
探索性测试可简单定义为:同时设计测试和执行测试。探索性测试比较适合于那些需求不是很明确的测试任务,或者执行一项新的测试任务时使用,它是传统测试的补充。
单元测试有两种模式:测试驱动模式和代码先行模式。
一般情况下,单元测试主要检查5方面问题:模块接口、局部数据结构、边界条件、独立的路径和错误处理。
单元测试的性能测试工具:AQTime是可以计算出每行代码执行时间的工具,可以测试检查出每一个方法或每一行代码的执行时间是多少;Ntime工具可以并行地运行同一个方法多次,查看能否达到预期的性能指标;Logiscope是一个用于单元测试功能齐全、性能优越的测试工具,可以实现广义单元测试的内容。
测试与调试的区别:
测试的目的是寻找和显示出存在的缺陷或者错误,测试是一种检验,经过测试,可能会发现一些错误的征兆,但常常不能直接从测试的结果中找出错误的根源。
调试是指发现错误或导致程序失效的错误原因,并修改程序以修正错误的过程。通常调试是测试之后的活动,即调试是在测试发现错误后消除错误的过程。
集成测试包括两种不同的方法:非增量式测试和增量式测试。增量式集成测试可以按照不同的次序实施,因此有两种不同的方法,也就是自顶向下结合和自底向上结合。
自顶向下测试的优点:它可以自然地做到逐步求精,一开始就能让测试者看到系统的框架。它的主要缺点是需要提供桩模块,并且在输入/输出模块接入系统以前,在桩模块中表示测试数据有一定困难。因为桩模块不能模拟数据,如果模块件的数据流不能构成有向的非环状形式,一些模块的测试数据便难以生成。同时,观察和解释测试的输出常常也比较困难。
自底向上测试的优点:由于驱动模块模拟了所有调用参数,即使数据流并未构成有向的非环状图,生成测试数据也无困难。如果关键的模块位于结构图的底部,那么自底向上测试具有优越性。它的主要缺点在于,直到最后一个模块被加进去之后才能看到整个程序(系统)的框架。
功能测试可细分为多种:逻辑功能测试、界面功能测试、易用性、安装测试等,其中最主要的是逻辑功能测试。
性能测试可分为一般性能测试、稳定性测试、负载测试和压力(强度)测试。
错误发生的平均时间间隔(Mean Time Between Failure, MTBF)是衡量系统的稳定性指标之一。
常用的可靠性模型可从黑盒测试和百盒测试两方面进行。黑盒方面的可靠性模型包括基本执行模型(Musa),分离富化模型(Jelinski-Moranda),NHPP模型和增强的NHPP模型(Goel-Okumoto),以及贝叶斯判定模型(Littlewood-Verrall)。
白盒方面的可靠性模型包括基于路径的模型(Krishna-murthy和Mathur)和基于状态的模型(Gokhale etal)。
压力测试的一个变型被称作敏感测试。在有些情况(最常见的是在数学算法中)下,在有效数据界限之内的一个很小范围的数据可能会引起极端的甚至是错误的运行,或者引起性能的急剧下降,这种情形和数学函数中的奇点相类似。敏感测试就是要发现在有效数据输入里可能会引发不稳定或者错误处理的数据组合。
软件测试分类
按测试阶段划分:单元测试、集成测试、系统测试、验收测试
按是否运行程序划分:静态测试、动态测试
按测试是否查看源代码划分:白盒测试、黑盒测试
按软件架构形态划分:面向对象软件测试、Web系统软件测试、嵌入式系统软件测试
其他情形划分:回归测试、冒烟测试、确认测试、恢复性测试、探究性测试
功能测试:逻辑功能测试、界面功能测试、易用性测试、安装测试、兼容性测试
性能测试:性能测试、稳定性测试、负载测试、压力(强度)测试、安全测试