目录
一、软件测试
1. 软件测试基础
2. 测试过程
3. 测试方法分类
4. 黑盒测试
(1)黑盒测试概述
(2)等价类划分方法
(3)边界值方法
5. 白盒测试
(1)白盒测试概述
(2)白盒测试的覆盖标准
(3)基本路径法
(4)循环测试法
(5)xUnit白盒测试
一、软件测试
1. 软件测试基础
传统: 测试是一种旨在评估一个程序或系统的属性或能力,确定它是否符合其所需结果的活动
测试目的:在程序中寻找错误
用Venn Diagram来理解测试
考虑一个程序行为全域,给定一段程序及其规格说明
- 集合S是所描述的行为
- 集合P是用程序实现的行为
-
设计测试用例集合T
设计测试用例时,应包括合理的输入和不合理的输入,以及各种边界条件,特殊情况下要制造极端状态和意外状态
测试用例(testing case):
- 测试用例是为特定的目的而设计的一组测试输入、执行条件和预期的结果
- 测试用例是执行的最小测试实体
- 测试用例就是设计一个场景,使软件程序在这种场景下,必须能够正常运行并且达到程序所设计的执行结果
测试用例的特征:
- 最有可能抓住错误的
- 不是重复的、多余的
- 一组相似测试用例中最有效的
- 既不是太简单,也不是太复杂
2. 测试过程
软件测试的V模型
3. 测试方法分类
- 按实施步骤划分:
- 单元测试 Unit Testing——由编写该单元代码的开发人员执行
- 单元测试环境
- 驱动模块(driver):模拟被测模块的上一级模块,接收测试数据,把这些数据传送给所测模块,最后再输出实际测试结果
- 桩模块(stub):模拟被测单元需调用的其他函数接口,模拟实现子函数的某些功能
- 集成测试 Integration Testing
- 在单元测试的基础上,将所有模块按照总体设计的要求组装成为子系统或系统进行的测试
- 集成测试的对象是模块间的接口,其目的是找出在模块接口上和系统体系结构上的问题
- 确认测试 Validation Testing
- 检查软件能否按合同要求进行工作,即是否满足软件需求说明书中的确认标准
- 系统测试 System Testing
- 系统测试是将已经集成好的软件系统作为一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其他元素结合在一起,在实际运行环境下进行的一系列测试
- 系统测试方法
- 功能测试、协议一致性测试
- 性能测试、压力测试、容量测试、安全性测试、恢复性测试
- 备份测试、GUI 测试、健壮性测试、兼容性测试、可用性测试
- 可安装性测试、文档测试、在线帮助测试、数据转换测试
- 验收测试 Verification Testing
- 验收测试是以用户为主的测试,一般使用用户环境中的实际数据进行测试
- 在测试过程中,除了考虑软件的功能和性能外,还应对软件的兼容性、可维护性、错误的恢复功能等进行确认
- α测试与β测试是产品在正式发布前经常进行的两种测试
- α测试是由用户在开发环境下进行的测试
- β测试是由软件的多个用户在实际使用环境下进行的测试
- 按使用的测试技术划分:
- 静态测试:走查/评审
- 动态测试:白盒/黑盒
- 黑盒测试:又称“功能测试”或“数据驱动测试”
- 它将测试对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明
- 白盒测试:又称“结构测试”或“逻辑驱动测试”
- 它把测试对象看做一个透明的盒子,它允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试
- 按软件组装策略划分:
- 非增量测试:整体集成
- 把所有模块按设计要求一次全部组装起来,然后进行整体测试
- 增量测试:自顶向下、自底向上、三明治(双向)
- 逐步将新模块加入并测试
- 自顶向下的集成测试:从主控模块开始,按软件的控制层次结构,以深度优先或广度优先的策略,逐步把各个模块集成在一起。较少需要驱动模块,但所需的桩模块数量巨大
- 自底向上的集成测试:从软件结构最底层的模块开始组装测试。不用桩模块。程序最后一个模块加入时才具有整体形象,难以尽早建立信心
- 三明治集成:一种混合增量式集成策略,综合了自顶向下和自底向上两种方法的优点
回归测试(Regression Testing)
- 回归测试是验证对系统的变更有没有影响以前的功能,并且保证当前功能的变更是正确的
- 回归测试可以发生在软件测试的任何阶段,包括单元测试、集成测试和系统测试,其令人烦恼的原因在于频繁的重复性劳动
4. 黑盒测试
(1)黑盒测试概述
黑盒测试(black-box testing):
- 又称“功能测试”、“数据驱动测试”或“基于规格说明书的测试”,是一种从用户观点出发的测试
- 将测试对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明
- 通常在软件接口处进行
- 原理:任何程序都可以看作是将输入定义域取值映射到输出值域的函数
用黑盒测试发现程序中的错误,必须在所有可能的输入条件和输出条件中确定测试数据,来检查程序是否都能产生正确的输出,但这是不可能的。因此,测试人员只能在大量可能的数据中,选取其中一部分作为测试用例
黑盒测试的实施过程
- 测试计划阶段
- 测试设计阶段
- 依据程序需求规格说明书或用户手册,按照一定规范化的方法进行软件功能划分和设计测试用例
- 输入数据和期望输出均从需求规格中导出
- 测试执行阶段
- 按照设计的测试用例执行测试
- 自由测试(作为测试用例测试的补充)
- 测试总结阶段
(2)等价类划分方法
等价类:输入数据的某个子集,在该子集合中的各个输入数据对于揭露程序中的错误都是等效的,并合理地假定“测试某等价类的代表值就等于对这一类其它值的测试”
等价类划分关键步骤:确定等价类和选择测试用例
基本原则:
- 每个可能的输入属于某一个等价类
- 任何输入都不会属于多个等价类
- 用等价类的某个成员作为输入时,如果证明执行存在误差,那么用该类的任何其他成员作为输入,也能检查到同样的误差
有效等价类
- 对于程序的规格说明来说是合理的、有意义的输入数据构成的集合
- 利用有效等价类可检验程序是否实现了规格说明中所规定的功能和性能
无效等价类
- 对程序的规格说明是不合理的或无意义的输入数据所构成的集合
- 无效等价类至少应有一个,也可能有多个
划分等价类的标准:完备测试、避免冗余
确定等价类的六大原则
- 原则1:在输入条件规定了取值范围或值的个数的情况下,则可以确立1个有效等价类和2个无效等价类
- 原则2:在输入条件规定了输入值的集合或者规定了“必须如何”的条件的情况下,可确立1个有效等价类和1个无效等价类
- 原则3:在输入条件是一个布尔量的情况下,可确定1个有效等价类和1个无效等价类
- 原则4:在规定了输入数据的一组值(假定n个)、并且程序要对每一个输入值分别处理的情况下,可确立n个有效等价类和1个无效等价类
- 原则5:在规定了输入数据必须遵守的规则的情况下,可确立1个有效等价类(符合规则)和n个无效等价类(从不同角度违反规则)
- 原则6:在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步的划分为更小的等价类
测试用例 = {测试数据+期望结果}
测试结果 = {测试数据+期望结果+实际结果}
(3)边界值方法
边界值分析是等价类测试的特例,主要是考虑等价类的边界条件,在等价类的“边缘”选择元素
使用边界值分析方法设计测试用例,首先应确定边界情况:
- 通常输入和输出等价类的边界,就是应着重测试的边界情况
- 选取正好等于、刚刚大于、刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值作为测试数据
边界值分析的原则
- 原则1:如果输入条件规定了值的范围,则应取刚达到这个范围的边界的值,以及刚刚超越这个范围边界的值作为测试输入数据
- 原则2:如果输入条件规定了值的个数,则用最大个数、最小个数、比最小个数少1,比最大个数多1的数据作为测试数据
- 原则3:将原则1和原则2应用于输出条件,即设计测试用例使输出值达到边界值及其左右的值
- 原则4:如果程序的规格说明给出的输入域或输出域是有序集合,则应选取集合的第一个元素和最后一个元素作为测试用例
- 原则5:如果程序中使用了一个内部数据结构,则应当选择这个内部数据结构的边界上的值作为测试用例
- 原则6:分析规格说明,找出其它可能的边界条件
5. 白盒测试
(1)白盒测试概述
白盒测试(又称为“结构测试”或“逻辑驱动测试”):把测试对象看做一个透明的盒子,它允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试
白盒测试主要对程序模块进行如下的检查:
- 对模块的每一个独立的执行路径至少测试一次
- 对所有的逻辑判定的每一个分支(真与假)都至少测试一次
- 在循环的边界和运行界限内执行循环体
- 测试内部数据结构的有效性
代码评审:靠人发现代码中不符合规范的地方、潜在的错误
代码性能分析:发现代码中的性能缺陷
白盒测试:发现代码中的错误!
白盒测试的特点:
- 以程序的内部逻辑为基础设计测试用例,又称逻辑覆盖法
- 应用白盒法时,手头必须有程序的规格说明以及程序清单
白盒测试考虑测试用例对程序内部逻辑的覆盖程度:最彻底的白盒法是覆盖程序中的每一条路径,但是由于程序中一般含有循环,所以路径的数目极大,要执行每一条路径是不可能的,只能希望覆盖的程度尽可能高些
(2)白盒测试的覆盖标准
对一个具有多重选择和循环嵌套的程序,不同的路径数目可能是天文数字
为了衡量测试的覆盖程度,需要建立一些标准,目前常用的一些覆盖标准从低到高分别是:
- 语句覆盖(Statement Coverage):
- 为了暴露程序中的错误,应选择足够多的测试数据,使被测程序中的每条语句至少应该执行一次
- 语句覆盖是最弱的测试标准
- 判定覆盖 (Decision Coverage)
- 比“语句覆盖”稍强的覆盖
- 执行足够的测试用例,使得程序中的每一个分支至少都通过一次
- 条件覆盖(Condition Coverage)
- 更强的覆盖标准
- 执行足够的测试用例,使得判定中的每个条件获得各种可能的结果
- 判定/条件覆盖(Decision/Condition Coverage) :
- 执行足够的测试用例,使得判定中每个条件取到各种可能的值,并使每个分支取到各种可能的结果
- 条件组合覆盖(Multiple Condition Coverage):
- 执行足够的测试用例,使得每个判定中多个条件的各种取值的可能组合都至少出现一次
(3)基本路径法
路径测试:设计足够多的测试用例,覆盖被测试对象中的所有可能路径
基本路径测试(Basic path test):
- 在程序控制图的基础上,通过分析控制构造的环行复杂性,导出基本可执行路径集合,从而设计测试用例
- 设计出的测试用例要保证在测试中程序的每一个基本独立路径至少执行一次。
4个步骤和一个工具方法
- 程序的控制流图:描述程序控制流的一种图示方法
- 程序圈复杂度:McCabe复杂性度量。从程序的环路复杂性可导出程序基本路径集合中的独立路径条数,这是确定程序中每个可执行语句至少执行一次所必须的测试用例数目的上界
- 导出测试用例:根据圈复杂度和程序结构设计用例数据输入和预期结果
- 准备测试用例:确保基本路径集中的每一条路径的执行
独立路径(基本路径):一条程序执行的路径,至少包含一条在定义该路径之前的其他基本路径中所不曾用过的边(即:至少引入程序的一个新处理语句集合或一个新条件)
计算圈复杂度:流图中区域的数量
- 给定流图G的圈复杂度V(G),定义为V(G)=E-N+2,E是流图中边的数量,N是流图中结点的数量
- 给定流图G的圈复杂度V(G),定义为V(G)=P+1,P是流图G中判定结点的数量
(4)循环测试法
循环测试是一种白盒测试技术,注重于循环构造的有效性
四种循环:简单循环,串接(连锁)循环,嵌套循环和不规则循环
简单循环测试
- 零次循环:从循环入口直接跳到循环出口
- 一次循环:查找循环初始值方面的错误
- 二次循环:检查在多次循环时才能暴露的错误
- m次循环:此时的m<n,也是检查在多次循环时才能暴露的错误
- n(最大)次数循环、n+1(比最大次数多一)次的循环、n-1(比最大次数少一)次的循环
嵌套循环测试
- 从最内层循环开始,设置所有其他层的循环为最小值
- 对最内层循环做简单循环的全部测试。测试时保持所有外层循环的循环变量为最小值;另外,对越界值和非法值做类似的测试
- 逐步外推,对其外面一层循环进行测试;测试时保持所有外层循环的循环变量取最小值,所有其它嵌套内层循环的循环变量取“典型”值
- 反复进行,直到所有各层循环测试完毕
- 对全部各层循环同时取最小循环次数,或者同时取最大循环次数对于后一种测试,由于测试量太大,需人为指定最大循环次数
串接循环测试
- 如果各个循环互相独立,则串接循环可以用与简单循环相同的方法进行测试
- 如果有两个循环处于串接状态,而前一个循环的循环变量的值是后一个循环的初值;则这几个循环不是互相独立的,则需要使用测试嵌套循环的办法来处理
非结构循环测试
- 对于非结构循环,不能测试,应重新设计循环结构,使之成为其它循环方式,然后再进行测试
(5)xUnit白盒测试
xUnit—x代表不同的编程语言,xUnit是相应的单元测试工具
jUnit的核心Assert方法
JUnit3中的setUp()方法,在JUnit4中使用@Before标识;
JUnit3中的tearDown ()方法,在JUnit4中使用@After标识;
JUnit3中的testXXX()方法,在JUnit4中使用@Test 标识。