文章目录
- 一、软件测试基础
- 1.1 基本概念
- 1.2 软件测试模型
- 1.3 软件测试的分类
- 二、基于规格说明的测试技术(黑盒)
- 2.1 重要的测试方法
- 1. 等价类划分法
- 2. 边界值法
- 3. 判定表法
- 4. 因果图法
- 2.2 其他测试方法
- 三、基于结构的测试技术(白盒)
- 3.1 静态测试
- 3.2 动态测试
一、软件测试基础
1.1 基本概念
- 软件测试的目的是“保证软件质量”。需要指出的是,是否符合应用需求并不是软件测试的唯一目的,测试必须考虑软件对法规的符合性、标准的符合性以及如商务要求等方面的符合性。
- 软件测试的对象是软件,包含程序、数据和文档
- 验证和确认:验证是判断生产者是否(按需求规格)正确地构造了软件,或者说是不是“
正确地做事”。而确认则是检验软件是否有效,是否满足用户的预期用途和应用需求。由于需求规格不一定真实体现了用户的特定预期用途或应用要求,通过验证的软件也就不一定能够通过确认。 - 软件在需求分析和设计阶段同样会引入缺陷,而且占比均超过编码阶段。在需求分析阶段引入的缺陷比例通常超过40%,在设计阶段引入的缺陷也在30%以上,而编码产生的缺陷低于30%
- 一般而言,在软件工程活动中,缺陷从产生到发现的间隔时间越短,修复的代价就越小,当缺陷从一个工程阶段跨入后一个工程阶段时,修复的代价将以指数级增长。正因为如此,软件工程活动中要努力做到缺陷早发现早排除,对应的测试活动就不能是编码完成之后的一个阶段性工作,而是贯穿软件工程的各个阶段,力争通过测试尽早地发现缺陷。
- 软件质量的定义:“在规定条件下使用时,软件产品 满足明确的或隐含的要求的能力”
软件质量包含软件测试,软件测试是保证软件质量的一种措施或手段。
1.2 软件测试模型
- V模型
- W模型: W模型是对V模型的一个重要改进,充分体现了尽早开展测试的原则,并将V模型中以发现缺陷为目标上升为保证软件质量为目标。
w模型实际上是两个V的叠加,一个V描述开发过程,另外一个V描述测试过程。但测试的起始时机不再是编码结束之后,而是从需求分析时开始,且与开发的每一个阶段活动同步进行。
- H模型:改进了W和V模型高度依赖于开发的瀑布模型的缺陷
H模型把测试活动从软件开发过程中独立出来,在软件过程的任何一个时间点上,只要测试条件满足即开展测试。
- 敏捷测试模型: 敏捷测试源于敏捷开发。敏捷测试是敏捷开发的组成部分,需要与开发流
程良好融合
1.3 软件测试的分类
-
按工程阶段划分的测试:如果按软件开发的瀑布模型,测试活动也可以划分为几个主要的阶段,包括单元测试、集成测试、系统测试、确认测试和验收测试等。
- 单元测试是最小单位的测试活动,也称为模块测试。是封闭在单元内部的测试,关注一个单元是否正确地实现了规定的功能、逻辑是否正确、输入输出是否正确,从而寻找模块内部存在的各种错误,其测试内容包括模块接口、局部数据结构、模块内路径、边界条件和错误处理。依据是模块的详细设计文件,可能需要构造驱动模块或桩模块来支持单元测试。
- 集成测试是在软件的单元测试完成并修复了所发现的错误后,进行模块的集成时开展的测试。集成测试的主要任务是发现单元之间的接口可能存在的问题,目标是验证各个模块组装起来之后是否满足软件的设计文件要求。常见的集成策略有一次性集成和增量式集成。
- 系统测试的目标是确认软件的应用系统能否如预期工作并满足应用的需求。系统测试的对象是应用系统,除软件外可能还包括硬件、网络及数据,并且需要在一个比较真实的环境下进行。采用黑盒测试方式,并只能由独立的测试团队、用户或第三方机构进行。系统测试一般包括安全强度、性能、可靠性等测试。
- 确认测试和验收测试焦点放在与软件交付相关的验证与确认上。确认测试和验收测试与系统测试相似,以需求规格说明为依据,采用黑盒测试方法。
- 验收测试主要是确认软件的功能、性能及其他特性是否满足软件需求规格说明书中列出的需求,是否符合软件开发商与用户签订的合同的要求。验收测试由用户主导,开发方参与。
- 确认测试按用户参与程度不同分为:内部确认测试、α测试、β测试、验收测试。
-
按是否执行代码划分的测试: 可以将测试分为动态测试和静态测试
- 动态测试即通常意义上的测试,通过运行软件来发现错误或验证程序是否符合预期要求。
- 静态测试不运行软件,只做检查和审核,测试的对象包括需求文档、设计文档、产品规格说明书以及代码等。对各类文档的测试主要通过评审的方式进行,对代码采用走查和代码审查方式
-
按软件质量特性划分的测试: 根据国家标准中定义的软件产品质量的八个质量特性: 功能性、性能效率、兼容性、易用性、可靠性、信息安全性、维护性和可移植性
-
回归测试: 发生在软件有变动的情况下,如果这种变动是对缺陷的修复,回归测试首先要验
证缺陷是否确实被正确修复了,然后测试因此次缺陷修复而可能影响到的功能是否依然正确
二、基于规格说明的测试技术(黑盒)
- 测试用例的编写
①测试用例规格说明
:该文档标识了测试覆盖项,以及从一个或多个特征集的测试依据导出的相应测试用例
② 测试覆盖项指的是使用测试设计技术从测试条件中导出的,预计未来的测试用例将覆盖的内容
③ 针对每个测试覆盖项再进一步导出测试用例
2.1 重要的测试方法
1. 等价类划分法
- 定义:把程序的输入域划分成若干部分(子集),然后从每个部分中选取少数代表性的数据作为测试用例。每一类的代表性数据在测试中的作用可以等价于这一类中的其他所有值
- 常见的划分等价类的方式包括按区间划分、按数值划分、按数值集合划分、按限制条件或
规划划分、按处理方式划分等 - 建立等价类
- 确定测试用例步骤
2. 边界值法
- 错误更容易发生在输入域的边界或者说极值附近,而非输入域的中间部分
- 二值基本边界值分析: 如果有一个n变量的软件输入域,使其中一个变量取略小于
最小值、最小值、正常值、最大值、略大于最大值
这样五种选择,其余的所有变量取正常值。该n变量软件输入域的边界值分析会产生4n+1
个测试用例。 - 三值基本边界值分析: 如果有一个n变量的软件输入域,使每个变量取
略小于最小值、最小 值、略大于最小值、正常值、略小于最大值、最大值、略大于最大值
这样七种选择,其余的所有变昌里取正常值。该n变量软件输入域的边界值分析会产生6n+ 1
个测试用例。
3. 判定表法
- 判定表展示出输入条件与输出结果的对应关系。判定表测试以判定表的形式使用了测试项条件(原因)和动作(结果)之间的逻辑关系(判定规则)模型。
- 判定表通常由四个部分组成
- 建立判定表
4. 因果图法
- 因果图是一种简化了的逻辑图,能直观地表明输入条件和输出动作之间的因果关系。
- 因果图中一般以左侧为原因,右侧为结果
- 为了表示原因与原因之间、结果与结果之间可能存在的约束条件,在因果图中可以附加一
些表示约束条件的符号。
- 利用因果图导出测试用例需要经过以下几个步骤:
① 分析程序规格说明的描述中,哪些是原因,哪些是结果。原因常常是输入条件或是输入条件的等价类,而结果是输出条件。
② 分析程序规格说明的描述中语义的内容,并将其表示成连接各个原因与各个结果的“因果图
③ 标明约束条件。由于语法或环境的限制,有些原因和结果的组合情况是不可能出现的。为表明这些特定的情况,在因果图上使用若干个标准的符号标明约束条件。
④ 把因果图转换成判定表。
⑤ 为判定表中每一列表示的情况设计测试用例
2.2 其他测试方法
- 分类树法
- 案例说明
分类树划分完毕之后,可以通过结合表的方式将各个叶子结点的内容结合而成测试用例,如图所示。分类树的划分过程和等价类划分有点类似,但两者的区别在于,分类树方法中所划分出的类是完全不相交的,而在等价类划分中,它们某些时候也可能会重叠。
- 语法测试
- 在语法测试中,应基于两个目标来设计测试用例:
① 正面测试,设计的测试用例应以各种方式覆盖有效语法
② 负面测试,设计的测试用例应故意违反规则语法。
- 场景测试
- 场景测试使用被测软件与用户或其他系统之间的交互序列模型来测试被测软件的使用流程。测试条件是需要在测试中覆盖的基本场景和可选场景(即用户和系统交互的事件流用序列组成一个场景)。
三、基于结构的测试技术(白盒)
3.1 静态测试
- 静态测试是在不运行代码的情况下,通过一组质量准则或其他准则对测试项进行检查的测试。相对于动态测试而言,静态测试的成本更低,效率较高,更重要的是可以在软件生存周期的早期阶段即发现软件的缺陷。
- 静态分析是一种检查代码的方法(无论是源代码或对象/可执行级别),无需执行程序。它提供了一种机制,可以审查代码结构、控制流和数据流,检测潜在的可移植性和可维护的问题,计算适当的软件质量测度。
控制流分析
:一种常见的控制流分析方法是通过生成程序的有向控制流图来对代码进行分析。控制流图使用如图的流图符号来描述逻辑控制流,其中用圆形节点表示基本代码块,节点间的车向边代表控制流路径,反向边表示可能存在的循环。
- 计算圈复杂度
e代表控制流图中的边的数量
n代表在控制流图中的节点数量
P表示控制流图中的判定节点数
A表示流图中的封闭区域数目。
数据流分析
:数据流指的是数据对象的顺序和可能状态的抽象表示。数据值的变量存在从创建、使用到销毁的一个完整状态。- 数据流分析的作用是用来测试变量设置点和使用点之间的路径。这些路径也称为“定义-使用对”。对“定义-使用对”的检查能快速发现软件的定义和使用异常方面的缺陷
接口分析
:接口一致性是程序的静态错误分析和设计分析要共同研究的题目。接口一致性的设计分析可以检查模块之间接口的一致性和模块与外部数据库之间接口的一致性。
3.2 动态测试
- 基于结构的动态测试主要关注语句、分支、路径、调用等程序结构的覆盖,为了设计较少的用例,达到更高的覆盖率甚至100%的覆盖率,动态测试关键的是用例设计。
- 基于结构的动态测试用例设计,其设计基础是建立在对软件程序的控制结构的了解上的。原则上应做到:
- 常见的测试用例设计方式可以分为基于
控制流和数据流
两大类
- 基于控制流
- 语句测试(Statement Testing): 选择足够多的测试数据,使被测程序中每条语句都要被经历到
- 分支测试(Branch Testing):使得程序中的每个分支都要被经历到——哪怕这个分支上没有语句
- 判定测试(Decision Testing):使得程序中的每个判定语句的取值都要被经历到。
- 条件覆盖:使得每一判定语句中每个判定条件的可能值至少满足一次。
- 分支条件测试(Branch Condition Testing):设计足够的测试用例,使得每个判定语句的取值,以及每个判定条件的取值都能被覆盖到
- 分支条件组合测试(Branch Condition Combination Testing):要求设计足够的测试用例,使得每个判定语句中的所有判定条件的各种可能组合都至少出现一次。有3个条件,组合一共有2^3=8种可能组合。
- 修正条件判定测试(MCDC):要求满足两个条件:首先,每一个程序模块的入口和出口点都要考虑至少要被调用一次,每个程序的判定到所有可能的结果值要至少转换一次;其次,程序的判定被分解为通过逻辑操作符(and、or)连接的bool条件,每个条件对于判定的结果值是独立的。
MCDC测试只需要n+1
个测试用例即可实现100%覆盖率。