目录
软件质量保证与测试
测试概述:
对软件测试的理解:
软件缺陷:
定义:
外在表现形式:
产生的原因:
软件自身的特点
团队合作
设计和实现问题
管理问题
分布情况:
修复成本:
如何降低缺陷、提高软件质量?
预防措施:
需求分析避错准则
设计阶段避错准则
编码阶段避错准则
高质量编码:
测试模型:
V模型
不足:
W模型( W = V + V)
V&V
W模型强调(把质量保护的思想投入到需求概要详细设计这一块---提前做预防):
优点:
PIE 模型
几个相关概念
缺陷(Fault):
错误(Error):
失败(Failure):
观察到缺陷的三个必要条件:
例子:
软件测试的技术原则
名词解释:
穷举测试是不可能的
测试用例设计是关键
杀虫剂效应:
缺陷存在群集现象(二八原则):
测试的生命周期
1. 测试需求分析
2. 测试计划
测试何时停止:
3. 测试设计
测试用例--测试的灵魂
什么是良好的测试用例?
4. 测试开发
5. 测试执行和记录
6. 测试总结
缺陷报告单:
组成:
软件缺陷的级别:
软件测试的分类
静态测试:
概念:
静态测试包括
常用的静态测试方法:
代码检查
代码检查的主要内容
代码检查优越性
代码检查局限性
代码检查的几种方式
桌面检查:
代码审查:
常见代码审查清单
代码走查
代码审查与代码走查的区别
静态结构分析
白盒测试
(动态)白盒测试方法:
控制流分析和数据流分析(了解):
if:
while:
do-while
for
break和continue
switch语句
例题:
基本路径与主路径测试:
圈复杂度
路径:
简单路径
主路径
基路径
测试路径:
主路径的概念:
基本路径应满足:
覆盖:
基本路径覆盖:
求主路径:
主路径覆盖 :
求覆盖所有主路径的测试路径集
逻辑覆盖法:
1.语句覆盖
2.判定覆盖:
3.条件覆盖
4.条件/判定覆盖
5. 条件组合覆盖
例题:
覆盖标准对比:
6.修正条件/判定覆盖(MC/DC!!
修正条件/判定覆盖(MC/DC覆盖)要求为:
例题:
如何求满足MC/DC的测试用例集?
7.路径覆盖
循环测试
测试基本循环
测试嵌套循环
测试串接循环
非结构循环的测试
程序插装
怎么插桩:
插装的作用:
补充:白盒测试方法运用示例
设计步骤
基本路径
逻辑覆盖——以分支-条件覆盖为例
循环测试
整合
变异测试
程序变异:
变异算子
算子类别:
变异测试定义:
基本思想:
变异体无法被杀死的原因
变异分数的计算
如何变异
变异测试的优缺点
黑盒测试
概念:
黑盒测试的优缺点
常用的方法和技术有:
等价类划分法
等价类
等价类划分
等价类组合
等价类测试的步骤
等价类划分测试举例
2.边界值分析法
边界值分析法选择测试用例的原则
边界值的组合
1、一般边界值:单缺陷假设、只考虑有效值。
2、一般最坏情况边界值:多缺陷假设、只考虑有效值。
3、健壮边界值:单缺陷假设、考虑有效值和无效值
4、健壮最坏情况边界值:多缺陷假设、考虑有效值和无效值
例题1:
例题2:
决策表法
例题:
决策表的分类
决策表的建立步骤
1.列出所有的条件桩和动作桩,确定规则的条数 例如
2、填入条件的不同取值组合;
3、填入具体动作,得到初始判定表;
4、化简,合并一些具有相同动作的相似规则。
决策表对我们的软件测试有什么用呢?
练习1:
练习2
例3
小结
因果图法
定义
优点
画法:
采用因果图法设计测试用例的步骤,
应用因果图判定表的思想设计测试用例。
组合测试
概念
组合测试的数学基础
正交表:
利用正交表实现组合测试
测试步骤:
正交表如何构造、构造算法?(如何选择合适正交表,
正交表存在如下问题:
例子:
例子2
例3:
成对测试(pairwise coverage)
组合测试与成对测试的区别
正交实验法和组合测试:
蜕变测试
蜕变测试的出发点 :
蜕变测试的基本理论
蜕变测试(metamorphic testing)
蜕变测试过程
蜕变测试的例子
场景法
事件流:
例题:
错误推测法
覆盖:
极小测试用例集:
最小测试用例集:
覆盖程度:
准则包含:
覆盖率:
要贯穿于整个软件生存期
要预防为主,发现为辅
需要客观性、独立性
最终标准都应追溯到用户需求
应妥善保存一切过程文档
(G.J.Myers给出与测试相关的三个要点:)
测试是为了证明程序有错,而不是证明程序 无错误
一个好的测试用例是在于它能发现至今未发现的错误
一个成功的测试是发现了至今未发现的错误的测试
(在IEEE提出的软件工程标准术语中,软件测试被 定义为:)
使用人工或自动手段运行或测试某个系统的过程,其目的在于检验它是否满足规定的需求或弄清楚预期结果与实际结果之间的差别。
(IEEE729-1983对缺陷有一个标准的定义)
从产品内部看,缺陷是软件产品开发或维护过程中存在的错误、毛病等问题
从产品外部看,缺陷是系统所需要实现的某种功能的失效或违背
(错误、缺少、多余、未明确指出但应有、用户不满意)
软件出现了产品说明书指明不会出现的错误
软件未达到产品说明书的功能
软件功能超出了产品说明书指明的范围
软件未达到产品说明书虽未指出但应达到的目标
软件难以理解、不易使用、运行速度缓慢,最终用户认为不好
软件自身特点 团队合作 设计和实现问题 管理问题
项目期限的压力 产品的复杂度 沟通不良 开发人员的疲劳、压力或受到干扰 缺乏足够的知识、技能和经验 不了解客户的需求 缺乏动力
1.软件本身的实际需求不清晰,导致设计目标偏离实际需求,从而引起功能或产品特征上的缺陷。
2.软件系统结构非常复杂。 不令人满意的架构设计 ;对象、类太多,很难完成各种对象、类相互作用的组合测试; 隐藏着一些参数传递、方法调用、对象状态变化等方面问题
3.系统运行环境复杂,不仅用户使用的计算机环境千变万化,包括用户的各种操作方式或各种不同的输入数据,容易引起一些特定用户环境下的问题
4.由于通信端口多、存取和加密手段的矛盾性等,会造成系统的安全性或适用性等问题
1. 系统需求分析时对客户的需求理解不清楚,或者和用户的沟通存在一些困难。
2. 不同阶段的开发人员相互理解不一致。
3. 对于设计或编程上的一些假定或依赖性,相关人员没有充分沟通。
4. 项目组成员技术水平参差不齐,新员工较多,或培训不够等原因也容易引起问题。
1.系统结构设计不合理、算法选择不科学,造成系统性能低下。
2.没有考虑系统崩溃后的自我恢复或数据的异地备份、灾难性恢复等问题,从而存在系统安全性、可靠性的隐患。
3.对程序逻辑路径或数据范围的边界考虑不够周全,漏掉某些边界条件,造成容量或边界错误。
4.算法错误:在给定条件下没能给出正确或准确的结果。
5.计算和精度问题:计算的结果没有满足所需要的精度。
6.接口参数传递不匹配,导致模块集成出现问题。
1.缺乏质量文化,不重视质量计划,对质量、资源、任务、成本等的平衡性把握不好,容易挤掉需求分析、评审、测试、等时间,遗留的缺陷会比较多。
2.开发流程不够完善和规范,存在太多的随机性和缺乏严谨的内审或评审机制,容易产生问题。例如对需求变化、设计更改、代码修正等因素缺乏严格规范的管理机制,导致开发过程难以稳步推进。
3.开发周期短,需求分析、设计、编程、测试等各项工作不能完全按照定义好的流程来进行,工作不够充分,结果也就不完整、不准确,错误较多;周期短,还给各类开发人员造成太大的压力,引起一些人为的错误。
4.文档不完善,风险估计不足等。
规格说明书 54% 设计 25% 代码15% 其他 6%
需求--设计--编码-开发测试--单元测试--集成测试--系统测试--发布(实际使用)
需求分析阶段缺陷修复成本低 实际使用阶段缺陷修复成本最高
(同功能点不同时期的测试时间:单元测试<集成测试<系统测试)
缺陷预防 :减少缺陷注入的机会(软件质量最高境界:Bug消除在送测前
缺陷消除(检测、修复)
减少缺陷注入的机会
软件避错设计技术
需求分析避错准则
设计阶段避错准则
编码阶段避错准则
高质量编程
需求分析人员和用户密切合作,清楚地说明并完善需求;
需求分析组人员间采用统一的需求建模方法;
需求分析自顶向下、逐层分解、不断细化;
必须编制规范的需求规格说明文档(正确、无歧义、完整等);
必须进行需求外部评审,确保需求理解的一致性和准确性
需求变更遵循制定的变更规范; ……
模块化和模块独立性,低耦合、高内聚
模块规模适中(建议小型60行,中型60~150行,大型200行,不超过500行)
适当的扇入、扇出
限制圈复杂度(控制流的复杂性) ……
程序设计语言选择,语言统一,使用编译程序中符合标准的部分编程,尽量减少非标准部分等
程序设计风格,命名规则、注释、排版、语句简单明晰、不盲目追求高效率等 ……
• 好的代码风格对于软件质量的好处在于可以加快软件开发进度,提高软件的可移植性和增加了代码的可维护性。
• 好的程序风格可以定义宏使得数据类型与操作系统平台无关,提 高了软件的可移植性。
扩展:“匈牙利命名规则”
“匈牙利命名规则”: 以一个或者多个小写字母开始,这些字母表示变量的类型。 后面跟着变量含义,如果有两个或以上的单词组成,每个单词首字母大写。 如,iNumber,cName,cStudentName
对于一般标识符,适当地使用简写形式,以最短的组合词表达所需要表达的意义 SetSecValue, SetVarofSecondValue ?
程序中不要出现仅靠大小写区分的相似的标识符; int x,X ?
用正确的反义词组命名具有互斥意义的变量或相反动作的函数等; setValue(), getValue()
静态变量加前缀s_(表示static);
类的数据成员加前缀 m_(表示 member);
使用i、j、k、l、m 作为循环计数变量。 ……
开发与测试是先后关系,先开发后测试。
忽视了对需求分析,系统设计的验证和确认,需求的满足情况一直到后期的验收测试才被验证。
如果前期开发阶段没有有效的质量控制措施,到软件编码完成之后,通过测试发现大量缺陷和错误,再想提高软件质量,则成本会非常高,有时甚至已经不可能。
相对于V模型,W模型增加了软件开发各阶段中同步进行的验证和确认活动。
W模型由两个V字型模型组成,分别代表软件质量验证、确认、测试过程 和 软件开发过程。
验证Verification:是否正确地构造了软件?检验开发出的软件产品和设计规格说明书的一致性。
确认Validation:是否构造了正确的软件?检验产品功能是否满足用户的真实需求。
软件需求分析、软件设计等同样需要质量控制,应当及时进行验证和确认。
软件需求、软件设计阶段需要为后续的软件测试工作做准备、测试与开发是同步进行的。
验证、确认和测试等软件质量控制活动伴随着整个软件开发周期。
有利于尽早、全面的发现问题。例如,需求分析完成后,质量保证与测试人员就应该参与到对需求分析文档的验证和确认活动中,并尽早的发现问题。 有利于降低软件开发的总成本。因为越早发现问题,解决问题的成本就会越小。 有利于提前做好测试准备和测试设计。例如在需求分析阶段就可以及早进行验收测试设计,这将显著减少测试工作所产生的时延,加快项目进度。 局限?
软件测试中的PIE模型可以区分这些不同的现象,并明确了这些现象的转化条件: 假设某一个程序中有一个存在缺陷的代码行,在该软件的某次执行中,这个存在缺陷的代码行并不一定会被执行到; 就算是这个存在缺陷的代码行被执行到了,只要没有达到某个特定的条件,程序也并不会出错; 只有执行错误代码,达到某个特定的条件,程序的错误状态表现出来后被感知,才能发现程序中的缺陷。
静态存在于程序中的错误代码行。
执行错误代码后导致的内部错误状态。
一个与软件需求或者预期行为描述不相符的、外在的行为。即错误状态传播到软件外部被外部感知。
程序状态经常定义为所有变量的当前取值和程序运行的当前位置(程序计数器PC)
病人就医为例 病人给医生描述一系列症状(失效Failure) 为了协助诊断,医生需要检查病人的异常内部状态(错误Error),如高血压、心律不齐、高血糖等 医生尝试发现症状的根源,即病因(缺陷Fault)
PIE模型告诉我们,就算一个程序中有缺陷,但要通过动态测试观察到这一缺陷的外部表现,还需要三个必要的条件:
1、程序执行路径必须通过错误的代码(Execution-执行);
2、在执行错误代码的时候必须符合某个或者某些特定条件,从而触发出错误的中间状态(Infection-感染);
3、错误的中间状态必须传播到最后输出,使得观测到输出结果与预期结果不一致(Propagation-传播)。
穷尽测试是不可能的,应当进行测试设计,选择测试数据。
设计测试用例时,应该考虑各种情况,包括异常情况。
应当把尽早和不断的测试作为座右铭。
应充分注意问题群集现象。
避免“杀虫剂效应” 制定并严格执行测试计划,排除测试的随意性。
对测试发现的错误结果一定要有一个确认的过程。
测试规格要求应追溯到用户需求 。
通过测试的软件并不意味着没有任何缺陷。
测试必须考虑成本和效益,
测试需要适时终止。
保存一切测试过程文档。 ... ...
即便是一个大小适度的程序,其路径排列的数量也非常大,因此,在测试中不可能运行路径的每一种组合。
要根据测试的目的采用相应的方法设计测试用例,更多地发现错误,避免冗余,提高测试效率。
缺陷修改之后再进行测试时,采用同样的测试用例进行测试,效果打折扣.,多个版本迭代下来,最终这些相同的测试用例将不再能发现新的bug。 为了克服这种“杀虫剂效应”,测试用例需要进行定期评审和修改,同时需要不断增加新的不同的测试用例来测试软件或系统的不同部分,从而发现潜在的更多的缺陷。
一个软件如果只有20%的核心功能,但这核心功能是软件的灵魂,需要花费测试人员80%的时间,那么在这20%的核心功能发现的Bug也会非常多,未发现的Bug也会很多,这就是群集现象。
群集现象: 对发现错误较多的程序段,应进行更深入的测试。 一般来说,一段程序中已发现的错误数越多,其中存在的错误概率也就越大。 测试中的错误集中发生现象,这和程序员的编程水平和习惯有很大的关系。
测试需求分析 ->测试计划 ->测试设计-> 测试开发-> 测试执行和记录--> 测试总结
明确需要完成的测试任务、测试内容和要达到的测试要求。
测试需求可以由软件文档获取,例如软件的规格说明书中明确了软件具有某项功能,那么就需要测试这项功能是否实现。
测试需求除了有功能测试需求之外还可以有非功能测试需求,如性能测试需求、安全性测试需求。
描述所有要完成的测试工作,包括被测试项目的背景、目标、范围、方式、资源、进度安排、测试组织,以及与测试有关的风险等方面。
安排进度 分配资源、人员 确定测试的起始点和结束点 ... ...
当时间用光时
当继续测试没有产生新的失效时
当继续测试没有发现新缺陷时
当无法考虑新测试用例时
当达到所要求的覆盖时
一个参考标准: 测试用例的执行效率100%,通过率95% 如果做单元测试,关键模块的语句覆盖率要达到100%,分支覆盖率要达到85%
如何合理运用测试原则、方法、策略,设计测试方案和数据,尽可能降低测试成本,并尽可能多的发现软件中的缺陷和问题。
测试设计要兼顾测试的充分性和成本节约原则,综合运用多种测试方法、策略,合理设计测试数据,用尽可能少的测试数据发现尽可能多的软件缺陷和问题,减少测试工作量,提高测试效率。
测试用例(Test Case):由输入数据和预期结果组成
输入数据:数据、文件或操作序列
预期结果:后果和实际输出
能够在较大程度地检测出软件中存在的缺陷,也即揭示错误能力强。 如何评价缺陷检测有效性?
没有冗余:不包含重复的测试用例
测试用例内容清晰、格式一致、分类组织 ... ...
(拓展:
如何评价缺陷检测有效性?
缺陷检测的有效性可以通过以下指标来评价:
缺陷发现率:缺陷检测工具或方法发现的缺陷数量与实际存在的缺陷数量的比率。
缺陷修复率:发现的缺陷被修复的比率。
缺陷密度:单位代码行或功能点中的缺陷数量。
缺陷严重程度:缺陷对系统功能、性能、可靠性等方面的影响程度。
缺陷定位时间:从发现缺陷到定位缺陷的时间。
缺陷修复时间:从发现缺陷到修复缺陷的时间。
缺陷复发率:修复的缺陷再次出现的比率。
)
主要指开发测试脚本,有时也包括自动生成测试数据等。 软件测试需要重复执行软件,以便发现软件中的问题,测试开发的重要工作就是编写得到用于自动执行测试过程的代码,一般称之为测试脚本. 有时在需要大量测试数据的情况下,也可以编写程序或者通过其他工具自动生成一些测试数据。
执行测试过程,包括执行程序,输入测试数据,记录测试结果等。
执行测试用例:
对于手动测试:按事先准备好的手工过程进行测试,测试者输入数据、观察输出、记录发现的问题。
对于自动测试:启动测试工具,执行测试用例;
包括统计分析测试结果,报告缺陷,评估软件质量等。
描述缺陷细节的文档,包括缺陷的编号、缺陷类型、缺陷严重程度、缺陷产生可能性、缺陷优先级、缺陷状态、缺陷起源、缺陷来源、缺陷原因等。 软件缺陷的级别
致命的(fatal):系统或应用程序崩溃、死机、系统悬挂,或造成数据丢失、主要功能完全丧失等。
严重的(critical):功能或特性没有实现,主要功能部分丧失,次要功能完全丧失或致命的错误声明。
一般的(major):缺陷不影响系统的基本使用,但是没有很好地实现功能,没有达到预期效果。
微小的(minor):对功能几乎没有影响、产品及属性仍可使用 建议(suggestion):建议作适当的修改来改善程序运行状态、或对设计不合理、不明白的地方提出质疑
按测试阶段 单元测试 集成测试 确认测试 系统测试 验收测试
按是否被执行 静态测试 动态测试
按需要是否查看代码 白盒测试 黑盒测试
黑盒测试:又称功能测试、数据驱动测试或基于规格说明的测试。 被测程序被当作一个黑盒,不考虑程序内部结构和特性,测试者只知道该程序输入和输出之间的关系或程序的功能,依靠能够反映这一关系和程序功能的需求规格说明书确定测试用例,然后执行程序,检查输出结果的正确性。
白盒测试:又称结构测试、逻辑驱动测试或基于程序的测试。 它把程序看成是一个可以透视的盒子,能看清楚盒子内部的结构以及是如何运作的。 白盒测试依赖于对程序内部结构的分析,针对特定条件设计测试用例,对软件的逻辑路经进行测试。 白盒测试可以在程序的不同位置检验“程序的状态”以判定其实际情况是否和预期的状态相一致。
从测试执行者来区分 手工测试 自动化测试
手工测试:是指由测试人员手工执行测试活动,并记录测试结果,观察分析结果是否正确或者符合要求。当测试任务很重,需要执行非常多的测试数据时,手工测试是难以满足实际需要的。
自动化测试是指通过开发和使用软件分析和测试工具、测试脚本等来实现软件分析和测试过程的自动化,具有可重复性和高效率等特点。
按测试实施组织区分:开发者测试 用户测试 第三方测试
开发方测试也叫做α测试,是指在软件开发环境下,由开发方提供检测和提供客观证据,验证软件是否满足规定的要求。
用户测试是指在用户的应用环境下,由用户通过运行和使用软件,验证软件是否满足自己预期的需求。
第三方测试也叫做独立测试,是指介于软件开发者和软件用户之间的测试组织对软件进行的测试。
其他测试类型:回归测试 随机测试 变异测试 蜕变测试 组合测试
回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。
随机测试是根据测试说明书执行样例测试的重要补充手段,是保证测试覆盖完整性的有效方式和过程。
非功能性测试:安装测试 兼容性测试 性能测试 文档和帮助测试 保密性测试 压力测试 故障恢复测试
静态测试是指不需要执行被测程序,而是人工检查或者借助专用的软件测试工具来评审软件文档或程序,度量程序静态复杂度,检查软件是否符合编程标准,寻找程序的不足之处,降低错误出现的概率。
统计表明,30%--70%的代码逻辑设计和编码缺陷可以通过静态代码分析来发现和修复。
代码检查、静态结构分析、代码质量度量等。
语法检查:最基本的程序静态分析,编译器完成。
非语法类型缺陷:人工或借助静态分析工具。
主要内容包括
检查代码和设计的一致性,代码对标准的遵循,可读性,代码逻辑表达正确性,代码结构合理性等;
发现程序中不安全、不明确和模糊部分,找出程序中不可移植部分;
发现违背程序编写风格问题,其中包括变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等内容。
在实际软件开发过程中被普遍采用,测试业界实践表明,通过代码检查,可检测到程序中 30%甚至高达70%的程序逻辑设计及编码中的缺陷或者错误;
一旦发现错误,能在代码中精确定位,降低修复成本;
有时可以发现成批错误,如分散在多处的同一类型错误等。
不能有效查出高层次的设计错误、不明显的错误等
对比动态测试?
代码检查的主要方式包括: 桌面检查 代码审查 代码走查
程序员对自己的代码进行一次自我检查,包括阅读程序、对代码进行分析、对照错误列表检查程序、对程序推演测试数据等。 在实践中,可以采用交叉桌面检查的方法,两个程序员可以相互交换各自的程序来做检查,而不是自己检查自己的程序。
局限性:效率是较低。
随意性较大,检查哪些内容,如何检查,检查到何种程度?
自己一般不太容易发现自己程序中的问题。
由若干程序员和测试员组成小组,通过阅读、讨论、评价和审议,对程序进行静态分析的过程。
代码审查分两步:
负责人提前把设计规格说明书、控制流程图、程序文本及有关要求、规范等分发给小组成员,作为审查的依据。小组成员在充分阅读这些材料后,进入审查环节。
召开程序审查会。通过会议和集体讨论、评价和审议,以集体的智慧和不同的角度,找出程序中的问题,提出修改意见和建议。
1、数据引用错误
是否有引用的变量未赋值或未初始化? 数组引用,是否每个下标都在规定界限内? 是否有空指针引用? 假如一个数据结构在多个函数中引用,每个函数对该结构的定义是否相同? ... ...
2、数据声明错误
是否所有变量都进行了明确声明? 数组和字符串的初始化值是否正确? 变量是否赋予了正确的长度、类型和存储类型? 初始化是否与存储类型相一致? 是否有相似的变量名,如VOLT,VOLTS?
3、运算错误
是否存在非算术运算变量间的运算? 是否有混合模式的运算,如浮点数+整数? 赋值号左边的数据类型是否小于右边的类型或计算结果? 除法运算中除数可能为0? 运算结果是否不精确?如 10*0.1 == 1.0? 整数的运算是否使用不当?如 i/2*2 == i ?
4、比较错误
是否有不同类型变量间的比较,如字符串与数字相比? 比较运算符是否使用正确?如 至多、至少、不小于等的理解, >= 写成 > ?? 比较运算符与布尔运算符混用?
例如, 判断i是否在2--10之间,2x||y ? 比较三个数字是否相等,if(a==b==c) ? 判断数学关系x>y>z? 是否有小数或者浮点数的比较运算? 运算符的优先级是否正确理解? if(a==2&&b==2||c==2) 编译器计算布尔表达式的方式是否会对程序产生影响? if(x==0 && (x/y)>z)
5、控制流程错误
是否所有的循环、模块或子程序最终都终止? 没有满足循环入口条件,循环体是否有可能从未执行过?遗漏? for(i 循环体语句块(左右花括号)是否正确使用? 是否 switch 语句有 default 情况? 循环中嵌套的 switch语句是否正确? for(....) { switch ... case: break; ... ... } 6、接口错误 实参的数量、类型、顺序等是否与形参相匹配? 实参的计量单位是否与形参一致? 如 元、万元? 如果调用了内置函数,实参的数量、属性、顺序是否正确?如 strcpy() 是否改变了某个原本仅为输入值的形参? 7、输入/输出错误 是否所有的文件是使用之前都打开? 是否所有的文件是使用之后都关闭? 是否有判断文件结束的条件并正确处理? 是否正确处理类似于“File Not Found”这样的错误? 打印或者显示的文本信息中是否有拼写错误? 让人充当计算机,把数据代入程序,模拟代码的执行,看程序能不能正常执行下去,执行过程和状态是否正确,并能最终得出符合预期的结果。 代码走查过程也分为两步:第一步把材料先发给走查小组每个成员,让他们认真研究程序,然后组织代码走查会议。 开会的过程与代码审查不同,不是简单地读程序和对照错误检查表进行检查,而是让与会者“充当计算机”,由测试人员为被测程序准备一批有代表性的测试用例,提交给走查小组,走查小组开会,一起把测试用例代入程序,模拟代码的执行,分析检查程序的执行过程和结果。 代码走查与代码审查都是以小组为单位进行,但代码走查重在模拟程序的执行,它需要推演每个测试用例的执行过程和结果,把测试数据沿程序的运行逻辑走一遍,过程和中间状态记录在纸张或白板上以供监视检查。 白盒测试又称为结构测试或逻辑驱动测试,是针对被测试程序单元内部如何工作的测试,特点是基于被测试程序的源代码,而不是软件的需求规格说明。使用白盒测试方法时,测试者必须全面了解程序内部逻辑结构,检查程序的内部结构,从检查程序的逻辑着手,对相关的逻辑路径进行测试,最后得出测试结果。 基本路径测试法 主路径测试法 基于逻辑覆盖的测试法 针对循环的测试 基于数据流的测试 变异测试 ... ... 控制流图(Control flow graph,简称CFG)也叫控制流程图,它用图的方式来描述程序的控制流程,是对一个过程或程序的抽象表达。 在控制流图中,用节点来代表操作、条件判断及汇合点,用弧或者叫控制流线来表示执行的先后顺序关系。 控制流图可以通过简化程序流程图得到,简化后的流图只有两种图形符号:结点和控制流线。 结点用带标号的圆圈表示,可以代表一个或多个语句、一个处理框或一个判断框。 控制流线用带箭头的弧线表示,代表程序中控制流。 根据源代码构建控制流图时需注意: 控制流图仅仅关注逻辑走向,而不关注中间的每一条语句的具体含义。 在顺序结构中,尽管可能包含了多条语句(语句块),但是在控制流图仅仅用一个节点表示。 控制流图、圈复杂度、基本路径、根据基本路径设计测试用例 简单的用程序的大小来度量程序的复杂度是片面和不准确的。 程序中的控制路径越复杂,环路越多,则环路复杂度越高,环路复杂度用来定量度量程序的逻辑复杂度。 环路复杂度(又称为圈复杂度),是一种为程序逻辑复杂度提供定量尺度的软件度量。 计算公式: V(G)=m-n+2 ① 其中:m表示有向图G中有向边的个数; n表示有向图中的结点数; 下图,圈复杂度是4。 ②:V(G)=强连通的流图在平面上围成的区域数 ③: V(G)=二值判定结点数+1 上图中,流图中围成的区域有(b,c,d,f,b), (c,d,f,e,c),(g,h,E,g)和(S,a,b,g,E,S), 因此公式②计算得到的环形复杂度为4。 在右图中,判定结点分别为b,c和g,根据 公式③可得环形复杂度为:3+1=4。 注意公式③:若一个判定节点存在多于两个的输出分支,此时必须进行分支的拆分,使其等效的控制流图的每一个判定节点都仅包含2个输出分支。 路径:一个节点或者边的序列 路径长度:边的数目 单一节点可看作是长度为0的路径 子路径:路径p的子序列称为p的子路径 环:起点和终点相同的路径 在把程序抽象为有向图之后,我们把从程序入口到出口经过的各个节点的有序排列称为路径。路径表达式可以是节点序列,也可以是弧(有向边)序列。 程序中存在循环时,如果执行循环的次数不同,那么对应的执行路径就不同,例如表中路径3和路径4就是由于程序执行循环次数不同而形成的不同的路径。 路径编号 弧序列表示 节点序列表示 1 acde 1-2-3-4-5 2 abe 1-2-4-5 3 abefabe 1-2-4-5-1-2-4-5 4 abefabefabe 1-2-4-5-1-2-4-5-1-2-4-5 5 abefacde 1-2-4-5-1-2-3-4-5 ... ... ... ... ... ... 除了初始节点和终止结点外,该路径中没有任何一个节点出现两次, 那么就是一条简单路径 主路径:不是其他任何简单路径的子路径的简单路径。 意思是这一条简单路径不能成为比它长的简单路径的子路径,也就是不能被其他简单路径所包含,我们称这条路径为主路径。 例题: 主路径:[1,2,4,1],[1,3,4,1],[2,4,1,2],[2,4,1,3],[3,4,1,2],[3,4,1,3],[4,1,2,4],[4,1,3,4] 独立路径:是指一组以前没有处理的语句或者条件的一条路径。 基本路径:控制流图中所有独立路径的集合就构成了基本路径集 控制流图中一条开始于起始节点、结束于终止节点的路径 测试路径代表测试用例的执行 不是其他任何简单路径的子路径的简单路径 设计满足主路径覆盖的测试用 1)是一条从入口节点到出口节点的路径; 一个控制流图中,基本路径的最大数量可以用环路复杂度来表示。 圈复杂度给出了独立路径数的上限。 给定一个覆盖准则C所包含的测试需求集TR,测试用例集T覆盖准则C,当且仅当对TR中的每一个测试需求tr,T中至少存在一个测试用例t满足tr 设计测试路径使得图中每条主路径都被覆盖到 (1开头7结尾) 列举覆盖所有节点的路径集P 例如:广度搜索每个起始节点到其它节点的路径 将路径集P扩展为测试路径集TP 对不含终止节点的路径p,将其拓展到终止节点 根据TP生成覆盖所有主路径的测试路径集 对不被TP覆盖的主路径,根据TP拓展为测试路径 去除冗余测试路径 主路径覆盖在线工具: http://cs.gmu.edu:8080/offutt/coverage/GraphCoverage 逻辑覆盖是以程序内部的逻辑结构为基础的测试技术,通过对程序逻辑结构的遍历来实现对程序的测试覆盖。 常见的覆盖准则(标准)有:语句覆盖、判定覆盖、条件覆盖、条件/判定覆盖、条件组合覆盖、修正条件/判定覆盖等。 逻辑表达式(也称谓词):计算结果为布尔值的表达式 谓词可能包括 布尔变量 非布尔变量的比较(>, <, ==, >=, <=, !=) (返回值为布尔值的)函数 ¬(非)、 ∧(与)、∨(或) → (蕴含)、⨁(异或)、⟷(等价) 子句(简单条件):不包含逻辑运算符的谓词 语句覆盖又称为代码行覆盖或语句块覆盖,指选择足够多的测试用例,使得程序中的每一条可执行语句至少被执行一次。 设计若干测试用例运行被测程序,使得程序中每个判断(即决策语句)为真和为假两种结果都至少出现一次。如果判定表达式中有多个子句(即简单条件,简称条件),判定覆盖只关注这个判定表达式的最终结果,而不是每个条件的结果。 判定覆盖又称为分支覆盖 判断结果取真值就会执行取真分支,判断结果取假值就会执行取假分支。 每个判断的真假值都至少出现一次,相当于每个判断的取真分支和取假分支至少都经历一次。 有时一个条件的的取值就可以决定整个表达式的取值,无法判定内部条件错误。 分析:判定覆盖和语句覆盖的包含关系? 如果测试达到判定覆盖,则显然程序流程的所有分支都是会被测试到的,各个分支上的所有语句都会被测试到,所以只要满足判定覆盖,就必定会满足语句覆盖。 条件覆盖就是要求判断表达式中的每一个条件都要至少取得一次真值和一次假值。 例如,对于程序段,两个判断 If ( x>0 OR y>0) If (x<10 AND y<10) 四个条件 x>0 y>0 x<10 y<10 条件覆盖并不比判定覆盖强(甚至不一定比语句覆盖强),两者只是关注点不同,有时会把条件覆盖和判定覆盖结合起来使用,这被称之为条件/判定覆盖, 设计足够多的测试用例,使得判定表达式中每个条件的真/假取值至少都出现一次,并且每个判定表达式自身的真/假取值也都要至少出现一次。 a b c a (a 1 1 1 Y Y Y Y 1 2 3 Y Y N N 3 1 2 N Y Y N 2 3 1 Y N Y N 设计足够多的测试用例,使得每个判定中条件取值的各种组合都至少出现一次。显然满足条件组合覆盖的测试用例一定也是满足判定覆盖、条件覆盖和条件/判定覆盖的。 例如,对于程序段P1,两个判断 If ( x>0 OR y>0), If (x<10 AND y<10) 每个判定中有两个条件,而两个条件可能的组合情况有4种。 ( x>0 OR y>0) 4种组合; (x<10 AND y<10) 4种组合; 如下图:( x>0 OR y>0) 4种组合; (x<10 AND y<10) 4种组合; 测试编号 x y 第1个判定 第2个判定 条件x>0 条件 y>0 条件 x<10 条件y<10 case12 50 50 Y Y N N case13 -5 -5 N N Y Y case14 50 -5 Y N N Y case15 -5 50 N Y Y (条件组合与条件/判定的区别: 以上题为例:条件/判定法,只需YYNN,NNYY即可(当然也可以是YYYY,NNNN即可,或NNNN,YYYY即可,或NNYY,YYNN即可) 请给出 (A ∧ B) ∨ C满足下列要求的测试需求:判定覆盖 、条件覆盖 、条件组合覆盖 解: A B C 1 T T T T 2 T T F T 3 T F T T 4 T F F F 5 F T T T 6 F T F F 7 F F T T 8 F F F F 判定覆盖------1,4(使得(A ∧ B) ∨ C取得T与F即可,当然2与4等等都是可以的) 条件覆盖----1,8(也可以是2,7等组合) 条件组合覆盖--如1,3,6,8 (1)每个基本语句块都被覆盖了。满足语句覆盖 (2)每个简单条件都取过真值和假值。满足条件覆盖 (3)每个判定都得出过所有可能的输出结果。满足判定覆盖 (4)每个简单条件都曾独立地影响判定表达式的输出结果。(在其他所有条件不变的情况下,改变该条件的值使得判定结果发生改变。) 例如 判定表达式 Z= (A or B) and (C or D) 其中A、B、C、D是简单条件。 测试用例2和10覆盖条件A。 找出覆盖B,C,D的测试用例。 解: (1)列出条件的全组合。 (2)找出独立影响对。 (3)找出最小测试用例集。 例: 考虑复合条件表达式 A and B,其中A、B为简单条件。 测试用例编号 A B 表达式 1 T T T 2 T F F 3 F T F 4 F F F 例: 考虑复合条件表达式(A and B) or C,其中A、B、C为简单条件。 测试用例编号 A B C 表达式 1 T T T T 2 T T F T 3 T F T T 4 T F F F 5 F T T F 6 F T F F 7 F F T F 8 F F F F 重新整理每个条件能够独立影响输出的测试用例对。 找出最小的测试用例集TS={2,3,4,6} 测试用例编号 A B C 表达式 2 T T F T 3 T F T T 4 T F F F 6 F T F F 是指设计足够多的测试用例,使得程序中的所有可能的路径都至少被执行一次。 ID 输入数据 通过的路径 x y z TE1-014 2 0 4 1-4-5-6-7 TE1-015 1 1 1 1-2-3 TE1-016 2 1 1 1-2-6-7 TE1-017 3 0 0 1-4-5-3 基本循环: 复合循环: 对基本的简单循环进行测试的方法一般采用循环边界条件测试法 相当于对循环次数变量进行边界值测试,一般覆盖 7 个边界值点。 设 i 为实际循环次数,n 是最大循环次数, 那么测试用例应包括: 直接跳过循环体,让i=0; 只执行一遍循环体,让i=1; 执行两遍循环体,让i=2; 执行m遍循环体(2< m < n-1) ; 执行n -1遍循环体,让i=n-1; 正好执行 n 遍循环体,让i=n; 超出最大循环次数。 测试嵌套循环的方法为: 从最内层测试开始,其它层的循环变量固定; 按照简单循环的测试方法测试最内层的循环体; 向外扩展循环体,测试下一个循环: 外层循环变量固定;内层嵌套的循环体也固定; 继续本步骤直到所有的循环体均测试完毕。 测试串接循环的方法为: 如果相连接的循环体互相独立,那么按照简单循环测试每一个循环体即可。 如果相连接的循环体 1 的循环变量的最终结果是循环体 2 循环变量的初始值,那么可采用针对嵌套循环的方法来测试。 别测了, 先改设计吧!!!! 程序插装就是借助往被测程序中插入操作来实现测试的目的 (1)插入打印语句 (2)插入计数语句 统计覆盖率 记录变量的动态特性 运用基本路径或主路径测试方法设计相关测试用例 运用逻辑覆盖测试方法设计相关测试用例 运用循环测试方法设计相关测试用例 综合上面三个结果,并去除冗余 根据程序的特点增加相应的测试用例 解: 环复杂度 : 二值判定节点个数 + 1 =3+1=4 边的数目-节点的数目 + 2 = 14-12+2=4 测试用例: 1. 6-10->11->12-23->14->16-18->20->21->11->23->24->27 相应的测试用例: 测试输入 = ((10,-999),0,100) 预期结果= 10 2. 6-10->11->12-23->14->19->23 ->24->27 相应的测试用例: 测试输入 = ((-10,-999),0,100) 预期结果= -999 3. 6-10->11->23->25-26>27 相应的测试用例: 测试输入 = ((-999),0,100) 预期结果= -999 分支相应的测试用例 while (( value[i]!=-999) &&(inputNumber<100)) 相应的测试用例: 测试输入 = ((10,-999),0,100) 预期结果= 10 测试输入 = ((-999),0,100) 预期结果= -999 测试输入 = ((0…100,-999),0,100) 预期结果= 49 分支和相应的测试用例 if ((value[i]>=minimum) && (value[i]<=maximum)) 相应的测试用例: 测试输入 = ((10,-999),0,100) 预期结果= 10 测试输入 = ((-10,-999),0,100) 预期结果= -999 测试输入 = ((150,-999),0,100) 预期结果= -999 分支和相应的测试用例 if validNumber > 0 相应的测试用例: 测试输入 = ((10,-999),0,100) 预期结果= 10 测试输入 = ((-10,-999),0,100) 预期结果= -999 while (( value[i]!=-999) &&(inputNumber<100)) 相应的测试用例: 不执行循环 测试输入 = ((-999),0,100) 预期结果= -999 只执行一遍循环体 测试输入 = ((10,-999),0,100) 预期结果= 10 执行两遍循环体 测试输入 = ((10,20,-999),0,100) 预期结果= 15 测试用例 m (m=50) 遍循环体 测试输入 = ((0..49,-999),0,100) 预期结果= 24 n-1(99)遍循环体 测试输入 = ((0..98,-999),0,100) 预期结果= 49 n (100)遍循环体 测试输入 = ((0..99,-999),0,100) 预期结果= 49 n + 1(101)遍循环体 测试输入 = ((0..100,-999),0,100) 预期结果= 49 并集、去除冗余、必要时额外补充 程序变异通常只是一种轻微改变程序的操作。例如,有程序段 P1,可以用“>”来替换程序中的“>= ”,产生变异程序 P2。 是一种产生变异体的机制。 设计变异算子来模拟程序员可能出现的简单错误。 当变异算子作用于原始程序时,产生的变异体在语法上必须是正确的; 一个变异算子可能产生一个或者多个变异体。 某个变异算子一可能不产生任何变异体。 变异算子对编程语言有依赖性,已经开发的、与语言相关的变异算子有 Fortran, C, Ada, Lisp 和 Java等。 操作数替换算子类:将一个操作数替换为另一个合法的操作数; 表达式修改算子类:用新的的运算符或替换运算符来修改表达式; 语句修改算子类:修改整条语句,如删除动态内存释放语句来模拟内存泄漏故障。 对于面向对象的语言,传统的变异算子不能够检测到和类相关的缺陷,因此需要另外设计关于类的变异算子。类变异算子和类的特性相关,比如继承、多态和动态绑 定以及方法重载等。 有时也叫做“变异分析”,指先对程序进行变异,然后再来执行测试,以检验测试数据集是否有效。 如果一个已知的修改被植入到程序中,而测试结果不受影响,则说明测试不充分或者测试无效。 变异测试是一种对测试数据集的有效性、充分性进行评估的技术,以便指导我们创建更有效的测试数据集。 给定一个程序P,通过对程序P进行微小的合乎语法的改变,得到一组变异体M1,M2,...; 对程序P和变异体M都使用测试集T进行测试,如果某Mi在某个测试输入t上与P产生不同的结果,即P(t)≠Mi(t),称T不能区别P和Mi,称该变异体Mi被杀死; 若某Mi在测试数据集T的所有测试数据t上都与P产生相同的结果,即T中所有的测试数据t都使得P(t)=Mi(t),则称T不能区别P和Mi,称Mi没有被杀死。 测试数据集还不够充分; 变异体在功能上等价于原始程序,称这类变异体为等价变异体(equivalent mutant). 测试集T的变异分数记为MS(T), 其中:|D|表示:杀死的变异体数,|E|表示:等价的变异体数,|M|表示:生成的所有变异体数 变异算子, 做法:要检查验证测试数据的有效性,首先应当模拟常见的错误和疏漏来修改程序。如果连这些都发现不了,那测试数据的质量肯定是有问题的,需要进一步完善。 程序变异:基于良好定义的变异操作,对程序进行微小的合乎语法的修改,得到源程序的变异程序。 良好定义的变异操作可以是模拟典型的应用错误。 例如模拟操作符使用错误,把大于等于改写成小于等于; 强制出现特定数据,以便对特定的代码或者特定的情况进行有效地测试,例如使得每个表达式都等于0,以测试某种特殊情况; ... ... 把被测试软件看做一个打不开的黑盒子,不考虑软件的逻辑结构和内部特性,只是依据软件的规格说明书,运行软件,输入测试数据,根据运行结果,检验该软件的功能是否实现并符合要求、性能等其它特性是否满足用户需要。 黑盒测试是一种从用户观点出发,基于规格说明的测试。 又叫功能测试、数据驱动测试。 优点:不需要源代码;测试简单易行;能够发现软件设计中的问题;除了功能之外,还可以测试性能、安全性等其他特性。 缺点:无法对代码进行有针对性的测试,某些代码可能得不到测试;有时输出的结果可能碰巧正确,但软件内部在执行过程中可能已经出错了;黑盒测试以规格说明书为测试依据,如果规格说明书有误,黑盒测试是发现不了的。 边界值分析法、 等价类划分法、 决策表法、 因果图法、 正交测试法等。 某个元素相应的等价类是指,对某一个等价关系而言,与其等价的所有元素的集合。 简单地说,等价类是数据集的某个子集,等价类中的各个元素具有某种相同的特性。 例如按照奇偶性,整数可以分为奇数和偶数两个等价类。 从软件测试的角度来说,由于等价类中的各个元素具有相同的特性,所以对于发现或者揭露程序中的缺陷,它们的作用是等价的,或者说效果是相同的。 于是等价类划分法就合理地假定:对于某个等价类而言,只需要测试其中的某个代表数据,就等于对这一等价类中所有数据的测试。 把所有可能的输入数据,划分成若干个等价类, 各个等价类之间不应存在相同的元素; 所有等价类的并集应当是被划分集合的全集; 然后从每一个等价类中选取1个或者少量数据,作为测试数据去测试程序。 等价类可以分为有效等价类和无效等价类。 有效等价类:是指对于程序规格说明来说,合理的、有意义的输入数据构成的集合。利用它,可以检验程序是否实现了规格说明预先规定的功能和性能等特性。 无效等价类:是指对于程序规格说明来说,不合理的、无意义的输入数据构成的集合。利用它,可以检验程序能否正确应对异常的输入,而不至于产生不希望出现的后果。 分类依据 :是否考虑无效等价类 单缺陷假设还是多缺陷假设 分类 :弱一般等价类 强一般等价类 弱健壮等价类 强健壮等价类 弱一般等价类: 只考虑有效等价类、单缺陷假设 每个被测变量的有效等价类应至少出现一次。 强一般等价类: 只考虑有效等价类、多缺陷假设 覆盖每个被测变量的有效等价类的所有组合。 弱健壮等价类(传统的等价类测试): 考虑有效和无效等价类、单缺陷假设 每个被测变量的有效等价类应至少出现一次,对于每个无效等价类,设计一条测试用例只覆盖一个无效等价类。 强健壮等价类: 考虑有效和无效等价类、多缺陷假设 覆盖所有变量的有效和无效等价类的全部组合。 划分等价类(核心工作、也是最有挑战性的); 给每个等价类设置一个不同的编号; 编写一个新的测试用例,使其尽可能多地覆盖尚未覆盖的有效等价类,重复这一步直到所有有效等价类均被测试用例所覆盖; 当所有的有效等价类都被覆盖之后,进入下一个步骤。 编写一个新的测试用例,使其只覆盖一个无效等价类,重复这一步,直到所有无效等价类均被覆盖。 例一:在三角形问题中,输入条件要求: ● 类型:整数; ● 个数:三个数; ● 取值范围:在1到100之间 解答: (1)从输入参数的类型、个数、取值范围角度划分等价类 三角形问题的等价类 细化之后: 输入三个整数 有效等价类 编号 无效等价类 编号 整数 1 一边为非整数 二边为非整数 三边均为非整数 4 5 6 三个数 2 只有一条边 只有二条边 多余三条边 7 8 9 3 一边为零 二边为零 三边为零 10 11 12 一边 < 零 二边 < 零 三边 < 零 13 14 15 一边 > 100 二边 > 100 三边 >100 16 17 18 (2)从输出域角度划分等价类 三角形问题有四种可能输出:非三角形,一般三角形,等腰三角形和等边三角形。利用这些信息来确定输出域等价类。 序号 【A,B,C】 输出 1 【3,4,5】 一般三角形 2 【0,1,2】 非三角形 3 【1,0,2】 4 【1,2,0】 5 【1,2,3】 6 【1,3,2】 7 【3,1,2】 8 【3,3,4】 等腰三角形 9 【3,4,4】 10 【3,4,3】 12 【3,3,3】 等边三角形 例2: 函数y = f (x1,x2) 输入变量的取值范围分别为: x1 ∈[a,d], x2 ∈ [e,g]。 根据函数的规格说明划分得到相应的等价类 : 边界值的思想:人们从长期的测试工作经验得知,大量的错误往往发生在输入和输出数据范围的边界或边界附近。 (1)如果输入条件规定了取值范围,则以此范围为基础设计测试数据。例如,程序的规格说明中规定:“重量在10公斤至50公斤范围内的邮件,其邮费计算公式为……”。则选择10,50,以及9.99,10.01,49.99和50.01进行测试。 (2)如果输入条件规定了取值的个数,则以个数为基础设计测试数据。例如,一个输入文件可以记录 30-30000个学生信息,则可取30,31,29,和,29999,30000及30001进行测试。 (3)如果指定了输出的范围和取值个数,则参考使用原则(1)(2)。 例如,某程序的规格说明了该程序的计算结果应[0,100]之间,那么可以设计测试用例,使得预期的计算结果应当为0,略大于0,略小于100,以及100。 例如,某程序一次可输出最多5个文件,那么可以设计测试用例,使得预期的输出分别为0、1、4、5个文件。 (4)如果明确知道程序中使用数组、链表等数据结构,则应当测试这个数据结构的边界情况。 例如,定义的数组容量是10,则测试数组为空、只包含一个元素、包含10个元素等边界情况。 (5)对被测程序深入分析从而发现隐含的边界条件。 例如,字符类变量的边界值? 整数变量的边界值? 屏幕上光标的边界值?等等 边界值的组合(一般边界值、一般最坏情况边界值、健壮边界值、健壮最坏情况边界值), 如果输入只有一个变量,考虑两种情况。 考虑单个变量在有效取值区间上的边界值,包括最小值,略高于最小值,略低于最大值和最大值。 { min, min+, nom, max-, max } 考虑异常,增加两个无效区间上的边界值,包括 略超过最大值以及略小于最小值的值。 { min-, min, min+, nom, max-, max, max+ } 只考虑有效值:仅考虑单个变量在有效取值区间上的边界值。 单缺陷假设:设计测试用例时每次只覆盖一个变量的边界值,其它变量选取正常值. 若有n个输入,总的测试用例个数为4n+1个。、 只考虑有效值:仅考虑变量在有效取值区间上的边界值。 多缺陷假设:将多个变量在有效区间上的边界值的所有组合情况作为测试用例集。 如果被测变量个数为n,则总的测试用例个数为5**n 考虑有效值和无效值:同时考虑变量在有效区间和无效区间上的边界值。 单缺陷假设:设计测试用例时每次只覆盖一个变量的边界值,其它变量应当用正常值。 如果被测变量个数为n,则测试用例个数为6n+1。 考虑有效值和无效值:同时考虑变量在有效区间和无效区间上的边界值。 多缺陷假设:将多个变量在有效区间上的边界值的所有组合情况作为测试用例集。 如果被测变量个数为n,则测试用例个数为7n 函数y = f (x1,x2) 输入变量的取值范围分别为: x1 ∈[a,d], x2 ∈ [e,g] 则其: 一般边界值有 4n+1=4*2+1 = 9 组, 一般最坏情况边界值有 5n = 25 组, 健壮边界值有 6n+1=6*2+1 = 13 组, 健壮最坏情况边界值有 7n = 49 组。 例:三角形问题采用边界值分析法 假设输入三条边的合法范围是 [1,100],采用一般边界值 测试用例编号 变量a 变量b 变量c 预期输出 Test1 50 50 1 等腰三角形 Test2 50 50 2 等腰三角形 Test3 50 50 50 等边三角形 Test4 50 50 99 等腰三角形 Test5 50 50 100 非三角形 Test6 50 1 50 等腰三角形 Test7 50 2 50 等腰三角形 Test8 50 99 50 等腰三角形 Test9 50 100 50 非三角形 Test10 1 50 50 等腰三角形 Test11 2 50 50 等腰三角形 Test12 99 50 50 等腰三角形 Test13 100 50 50 非三角形 若增加健壮性边界测试,在上表基础增加测试用例: 测试用例编号 变量a 变量b 变量c 预期输出 Test14 0 50 50 请输入1-100的三个整数 Test15 101 50 50 请输入1-100的三个整数 Test16 50 0 50 请输入1-100的三个整数 Test17 50 101 50 请输入1-100的三个整数 Test18 50 50 0 请输入1-100的三个整数 Test19 50 50 101 请输入1-100的三个整数 决策表:用于表述和分析复杂逻辑关系,适用于描述在不同条件下多种可执行动作的组合问题。 决策表由四个部分组成。 条件桩:列出了问题得所有条件。 动作桩:列出了问题规定可能采取的操作。 条件项:针对所有条件的取值列出不同条件取值的组合。 动作项:列出在条件项的各种取值情况下应该采取的动作。 规则:任何一个条件组合的特定取值及其相应要执行的操作,在决策表中对应为纵向贯穿条件项和动作项的一列。 例如,下表是一张“读书指南”决策表。其中:Y为真值,N为假值。 规则 选项 1 2 3 4 5 6 7 8 问题 你觉得疲倦吗? Y Y Y Y N N N N 你对书中内容感兴趣吗? Y Y N N Y Y N N 书中内容使你胡涂吗? Y N Y N Y N Y N 建议 请回到本章开头重读 √ 继续读下去 √ 跳到下一章去读 √ √ 停止阅读,请休息 √ √ √ √ 根据条件取值的个数,决策表可以分为有限项决策表和扩展项决策表。 有限项决策表:每个条件只有两个取值:真或假。 扩展项决策表:条件项的取值可以有很多个。 实际应用中针对特定问题选择合适的决策表类型。 1 2 3 4 5 6 7 8 问题 你觉得疲倦吗? 你对书中内容感兴趣吗? 书中内容使你胡涂吗? 建议 请回到本章开头重读 继续读下去 跳到下一章去读 停止阅读,请休息 规则 选项 1 2 3 4 5 6 7 8 问题 你觉得疲倦吗? Y Y Y Y N N N N 你对书中内容感兴趣吗? Y Y N N Y Y N N 书中内容使你胡涂吗? Y N Y N Y N Y N 建议 请回到本章开头重读 √ 继续读下去 √ 跳到下一章去读 √ √ 停止阅读,请休息 √ √ √ √ 化简就是将规则合并。如果有两条或多条规则具有相同的动作,并且它们的条件项很相似,则可以考虑能否把这些规则合并为1条规则,从而使得判定表得到简化。 例下图,可以把这两条规则合并成 1条规则,无关的条件其取值可用 横线填充。 判定表中每一条规则就是程序的一种处理逻辑,为每一条规则设计一个测试用例来对程序进行测试,相当于测试了程序的各种处理逻辑。 条件对应程序的输入或输入的等价类 动作对应程序的输出或程序的主要功能处理部分 规则对应测试用例 假设某程序规格要求如下:“……对功率大于50马力并且维修记录不全,或者已运行10年以上的机器,应给予优先的维修处理……”,假定,“维修记录不全”和“优先维修处理”均已在别处有更严格的定义。 确定规则的条数、列出所有的条件桩和动作桩: 填入条件项和动作顶,得到初始决策表 : 合并相似规则: 规则1、2可以合并;5、7可以合并;6、8可以合并。 根据最终决策表的5条规则,设计5个测试用例。 三角形问题示例: 条件、动作、规则条数?(假设输入数据均合法) NextDate问题示例 ; NextDate(月,日,年)是三个变量的函数。函数返回输入日期的下一个日期。变量月份、日期和年都是整数值,且满足下面的条件:1<=月份<=12,1<=日期<=31,1900<=年<=2060 解答: 条件桩 ? 输入条件细分等价类 使用扩展项决策表 动作桩 ? 细分动作 日期增1,日期复位为1,月份增1,月份复位为1,年份增1,不可能的日期 测试用例 规则1:测试输入 = (2007,7,19), 预期结果 = “2007-7-20” 规则2:测试输入 = (2007,7,31), 预期结果 = “2007-8-1” 规则3:测试输入 = (2007,9,25), 预期结果 = “2007-9-26” 规则4:测试输入 = (2007,9,30), 预期结果 = “2007-10-1” 规则5:测试输入 = (2007,11,31),预期结果 = “日期输入错误” 规则6:测试输入 = (2000,2,15), 预期结果 = “2000-2-16” 规则7:测试输入 = (2000,2,29), 预期结果 = “2000-3-1” 规则8:测试输入 = (2000,2,30), 预期结果 = “日期输入错误” 规则9:测试输入 = (2007,2,15), 预期结果 = “2007-2-16” 规则10:测试输入 = (2007,2,28), 预期结果 = “2007-3-1” 规则11:测试输入 = (2007,2,29), 预期结果 = “日期输入错误” 规则12:测试输入 = (2006,12,16), 预期结果 = “2006-12-17” 规则13:测试输入 = (2006,12,31), 预期结果 = “2007-1-1” 判定表能将复杂的问题按照各种可能的情况进行分解并全部列举出来,然后给出应当执行的操作,做到既简洁明了又避免遗漏。 适用于以下特征的程序: if-then-else逻辑 输入变量之间存在逻辑关系 输入与输出之间存在因果关系 很高的圈复杂度 在较为复杂的问题中,由程序规格说明不太容易直接得出决策表。 在输入条件比较多的情况下,直接使用决策表可能会产生过多的条件组合,从而导致决策表的列数太多。 条件之间可能会存在约束条件,所以很多条件的组合是无效的,也就是说,它们在决策表中完全是多余的。 解决方案: 可先画出因果图,根据因果图导出决策表,并利用因果图排除掉一些无效的条件组合,从而会使决策表的列数大幅度减少。 从用自然语言描述的程序规格说明描述中找出因和果,用因果图来表达它们的逻辑关系,因是输入条件,果是输出或程序状态的改变,也就是表达当输入是什么的情况下,结果会是什么? 然后根据因果图写出决策表,再由决策表来设计测试用例的方法。 因果图是一种将多个原因和不同结果之间的对应关系用图来表达的工具。 因果图的优点是可以用图解的形式,直观地表达输入条件的组合、约束关系和输出结果之间的因果关系,因果图一般和决策表结合起来使用。 在因果图中,通常: 用 Ci 表示原因,置于图的左部; 用 Ei 表示结果,置于图的右部。 Ci和Ei均可取值0或1,0 表示某状态不出现,1表示某状态出现。原因和结果之间以直线连接。 (1)关系 (2)约束 各个输入条件相互之间还可能存在某种关系,称为约束。例如:某些输入条件不可能同时出现。 输出状态之间也往往存在约束。 在因果图中,用特定的符号标明这些约束。 A.输入条件的约束有以下4类: ① E 约束(互斥):表示不同时为1,即a,b,c中至多只有一个1; ② I 约束(包含):表示至少有一个1,即a,b,c中不同时为0; ③ O 约束(唯一):表示a,b,c中有且仅有一个1;④ R 约束(要求):表示若a=1,则b必须为1。即不可能a=1且b=0;例如,手机号与验证码 B.输出条件约束类型 输出条件的约束只有 M 约束(屏蔽):若结果 a是1,则结果 b 强制为0。 一个文件管理系统的一段规格说明:“文件第一列字符必须A或B,第二列字符必须是数字,在此情况下文件被更新。如果第一列字符不正确,则提示错误信息“ERR1”;如果第二列字符不正确,则提示错误信息“ERR2”。 解: 原因:1——第一个字符是A 2——第一个字符是B 3——第二个字符是数字 结果: 70——文件进行更新 71——提示信息ERR1 72——提示信息ERR2 文件第一列字符必须A(原因1)或B(原因2),第二列字符必须是数字(原因3),在此情况下文件被更新(结果70)。 如果第一列字符不正确,则提示错误信息“ERR1”(结果71); 如果第二列字符不正确,则提示错误信息“ERR2”(结果72)。 有一个处理单价为5角钱的饮料自动售货机软件。其规格说明如下: 若投入5角钱,按下〖橙汁〗或〖啤酒〗的按钮,则相应的饮料就送出来。 若投入1元钱的硬币,按下〖橙汁〗或〖啤酒〗的按钮: 若售货机没有零钱找,则一个显示〖零钱找完〗的红灯亮,这时在投入1元硬币并按下按钮后,饮料不送出来而且1元硬币也退出来; 若有零钱找,则显示〖零钱找完〗的红灯灭,在送出饮料的同时退还5角硬币。 解答: (1)分析这一自动售货机软件的规格说明,列出原因和结果。 原因: 1.售货机有零钱找 2.投入1元硬币 3.投入5角硬币 4.按下橙汁按钮 5.按下啤酒按钮 结果: 1.售货机〖零钱找完〗灯亮 2.退还1元硬币 3.退还5角硬币 4.送出橙汁饮料 5.送出啤酒饮料 (2)画出因果图。 当因果图规模较大时,可以引入一些中间节点,表示处理的中间状态。本题的中间结点如下: 1. 投入1元硬币且按下饮料按钮 2. 已按下按钮(〖橙汁〗或〖啤酒〗) 3. 应当找5角零钱并且售货机有零钱找 4. 钱已付清 (3)在因果图中加上约束条件 (4) 把因果图转换成判定表 (5)根据判定表设计测试用例 在判定表中,阴影部分表示因违反约束条件的不可能出现的情况,应删去。第16列与第32列因什么动作也没做,也应删去。最后可根据剩下的16列,来设计测试用例。 组合测试的思想基于多参数故障模型 不同的参数之间相互作用是不一样的 组合测试(Combinatorial Test)是一种测试用例生成方法。它将被测应用抽象为一个受到多个因素影响的系统,其中每个因素的取值是离散且有限的。因素取值的组合划分不同强度(组合强度),如 两因素(Pairwise)组合测试要求生成一组测试用例集,能够覆盖任意两个因素的所有取值组合。 N因素(N-way,N>2)组合测试要求生成测试用例集,以覆盖任意 N 个因素的所有取值组合。 设待测软件的参数个数为 n,其中每个参数经过前期处理后共包含ai个取值。 确定组合测试所使用的t-way组合覆盖准则。 t-way组合覆盖:任意t个参数间的所有可能取值组合 若t=2,称为成对组合覆盖或两两组合覆盖:对于任意两个参数,它们的任意一对取值至少被一个测试用例所覆盖; 若t=3,称为三三组合覆盖;... ... 覆盖强度越高,相应生成的组合测试用例集的缺陷检测能力越强,测试代价也越大。 “均匀分散,整齐可比”?正交表。 正交表类似一个M*N矩阵,且具有以下性质 : 1.每一列中,不同的数字出现的次数相等。 2.任意两列中数字的排列方式齐全而且均衡,即两列中对应的数字是完全元素对并且每对出现的次数相等,即任意两列是均衡搭配。 概念: 因素 (Factors)。欲考察的变量称为因素(因子)。在软件测试中,指有多少个输入参数、变量或者配置。 水平 (Levels)。任何单个因素能够取得的值的个数。在软件测试中,指一个参数、变量或者配置允许取值的个数。 行数(Runs)。实验次数的多少,在测试中就是指多少个用例。 正交实验法思想:从大量的实验数据中挑选适量的、有代表性的数据,合理地安排实验的一种科学实验设计方法。 它根据正交性从全部可能的实验数据中挑选出部分有代表性的数据进行实验,这些有代表性的数据具有“均匀分散,整齐可比”的特点,是一种高效、快速、经济的实验设计方法。 正交实验法用在软件测试上,就是从大量的测试数据中挑选适量的,有代表性的进行实际测试,从而合理地安排测试的一种设计方法。 一个简单的正交表示例:三行、三列、每一列取值有两个:1和2。 每一列中,不同的数字出现的次数相等。 任意两列中数字排列方式齐全而且均衡; 任何两列有序对共有4种:<1,1>、<1,2>、<2,1>、<2,2>, 每种对数出现次数相等。 以上两点充分的体现了正交表的两大优越性,即“均匀分散性,整齐可比性”,这就是正交性。 1 1 1 1 2 2 2 1 2 2 2 1 正交表示例:九行、三列、每一列取值有两个:1、2和3。 假设某函数有3个输入变量,用A、B、C表示; 每个变量有三种可能的取值A1、A2、A3;B1、B2、B3;C1、C2、C3。 可以利用该正交表设计测试用例。 1 1 1 2 1 2 3 1 3 1 2 2 2 2 3 3 2 1 1 3 3 2 3 1 3 3 2 根据被测软件的规格说明书找出影响其功能实现的操作对象和外部因素,把它们当作因子; 把各个因子的不同取值当作状态,明确各个因子的水平数; 选择合适的正交表,把变量值映射到表中; 利用正交表进行各因子的状态组合,构造有效的测试输入数据集。 已经公开发布了一些构造好的正交表,可以从网络、书籍、相关软件等规范渠道获取。 在选择合适的正交表时,需要考虑因素(变量)的个数,因素水平(变量的取值)的个数,和正交表的行数。 如果因素数(变量个数)、水平数(变量值)都相符,那么直接套用符合需要的正交表即可。 若因素数(变量个数)、水平数(变量值)与现有能够查到的正交表不完全吻合,则需要找出能够包含该情况的正交表来使用。 若因子数和水平数与正交表不完全吻合,则找出包含该情况的正交表,具体需要满足: 正交表的列数不能小于因素数(变量个数); 正交表的水平数不能小于因素值(变量取值)的最大个数。 如果有多个符合条件的正交表,那么应选取行数最少的正交表。 不一定能够选择到满足条件的正交表; 正交表只能覆盖两个因素(变量)的全部组合,而在实际测试中测试人员可能希望部分参数之间实现更高强度的组合,如三个变量的全组合等。 例: word 中段落设置包含了换行设置共有三个选项,分别为: (1)按中文习惯控制首尾字符 (2)允许西文在单词中间换行 (3)允许标点溢出边界 解: 分析因素数目和水平数目,该设置共有三个选项:允许中文习惯控制首尾字符、允许西文在单词中间换行、允许标点溢出边界,因素的个数为3。 每个选项都包含了选择和不选择两种情况,每个因素的的水平数(取值的个数)相同均为2。 选择正交表: (1)表中的因数数目(列)大于等于3; (2)表中至少有三个因数的水平数大于等于 2; (3)行数取最少的一个。 依据上述原则,选择正交表。 将变量取值和实际含义进行映射: 可以得到最后的测试用例。 某系统有5个独立的参数配置变量(A,B, C,D,E) 变量A和B有两个取值(A1、A2)和(B1、B2) 变量C和D有三个取值(C1、 C2、C3和D1、D2、D3) 变量E有六个取值(E1、E2、E3、E4、E5、E6) 在现有正交表中,没有因素数、水平数都刚好符合的正交表。 解答: 成对测试是一种有效的测试用例生成技术,通过对测试变量的所有维度及值的组合,避免穷举测试所有维度的所有值及其组合来减少测试用例量 例如一个系统有三个输入参数 P = (p1, p2, p3), 其中 p1的取值V1= {a, b},p2的取值V2= {1, 2, 3},p3的取值V3= {x, y}。则下边的测试用例满足成对覆盖准则。 对于其中任意两个因素pi和pj而言,构成的测试用例个数为|Vi|×|Vj|,但是对于超过两个因素,满足成对覆盖准则的测试用例个数是不确定的。 人们一直采用各种策略实现满足成对测试需求,并且生成的测试用例个数尽可能地少,包括 CATS、AETG算法等。 3-way组合测试例子: 组合测试是一种测试方法,它通过测试系统中各个组件之间的各种组合情况,来发现可能存在的错误和缺陷。它主要针对系统中各种组合情况进行测试,包括不同的输入、参数、配置等情况。组合测试可以帮助测试人员发现系统中的交互问题和集成问题,以及可能存在的不兼容性和冲突。 成对测试是一种测试方法,它通过测试系统中两个参数之间的所有可能组合情况,来发现可能存在的错误和缺陷。它主要针对系统中两个参数之间的各种组合情况进行测试,包括不同的输入、参数、配置等情况。成对测试可以帮助测试人员发现系统中的参数问题和边界问题,以及可能存在的不兼容性和冲突。 判定表能将复杂的问题按照各种可能的情况进行分解并全部列举出来,然后给出应当执行的操作,做到既简洁明了又避免遗漏。适用于以下特征的程序: if-then-else逻辑 输入变量之间存在逻辑关系 输入与输出之间存在因果关系 很高的圈复杂度 判断软件是否存在缺陷的基本方法是将软件实际的运行结果和软件预期结果进行比较,所以软件运行的预期结果是构造软件测试用例最重要的因素之一。 在实际测试过程中,测试工程师无法构造或者说很难构造程序的预期结果,也就是说存在著名的Oracle(测试预言)问题。造成这个困难的原因有多个方面。 (1)程序的控制逻辑过于复杂,导致即使是简单输入也无法轻松地从输入推导出输出。 (2)程序的输出具有不确定性,或者没有明确输出。 (3)数据结果巨大,无法采用简单方法确认预期的输出结果。 蜕变关系:软件实际运行结果约束关系,称为蜕变关系。 假设在没有任何计算器或者直接的数学函数库的情况,程序P实现一个函数cos(x),除了特殊的角度例如30、45、60等特殊的角度以外,对于一个任意的角度,要判断其预期的输出是非常困难的。 考虑余弦函数具有的性质: 对程序而言,这些都是蜕变关系, 蜕变关系可能有多个。 利用程序执行结果之间的关系来测试程序,无需构造预期输出。 若程序P实现函数f,那么P必须遵守函数f的约束条件,否则程序P是不正确的。 例如,若程序P实现了余弦函数cos(x)的功能,若其输入变元x1,x2满足关系: x1+x2 = 0,那么P的输出值必须满足关系:P(x1) = P(x2)。 选取初始测试输入值、执行初始测试输入值、利用蜕变关系检查测试输入和程序输出是否满足蜕变关系。 蜕变关系的选择和构造是影响测试效果的最重要因素。在实际测试中个,可能存在三种情况: (1)程序实现正确,蜕变测试通过。 (2)程序实现不正确,蜕变测试未通过。 (3)程序实现不正确,但是蜕变测试通过。 有效的蜕变测试,应该使用尽可能少的测试用例发现其中的错误,可以通过变异分析等方法来验证蜕变测试用例的效果。 一个字符串的子序列,是指从该字符串中去掉任意多个字符后剩下的字符在不改变顺序的情况下组成的新字符串。 一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列LCS((Longest Common Subsequence)。 例如有两个序列分别cnblogs和belong,那么他们的最长公共子序列为blog。在这两个序列中,n、b、b、l、o、g、ng、bl、bo、bg、blo、blg、log、blog等等都是原序列的两个公共子序列,显然blog是所有子序列的中的最长子序列。 两个字符串的最长公共子序列具有如下关系: 若字符串A和B的前面增加1个不相同字符,A’=aA, B’=bB,且a,b均不出现在A或者B中,那么: LCS长度不变。 在字符串A和B的结尾增加1个不相同字符,A’=Aa, B’=Bb,且a,b均不出现在A或者B中: LCS长度不变。 在字符串A和B中的前面增加1个相同的字符: LCS长度增加1。 在字符串A和B中的结尾增加1个相同的字符: LCS长度增加1。 若字符串A和B中的第1个字符不相同,A=aA’,B=bB’且a≠b(a和b表示不同的字符),那么: LCS(A,B)=max(LCS(A’,B),LCS(A,B’))。 在程序输入参数中,交换字符串A和B的输入顺序,那么:LCS长度不变。 将序列A和B中的 字符逆序以后作为程序的输入,那么:LCS长度不变。 根据上述关系,可以构造最长公共子序列蜕变测试的用例。例如 前面介绍的黑盒测试方法,主要是针对单个功能点,不涉及到多个操作步骤的连续执行和多个功能点的组合。 对于复杂的软件系统,不仅要对单个功能点做测试,更重要的是,需要从全局把握整个系统的业务流程,确保在有多个功能点交叉存在复杂约束的情况下,测试可以充分覆盖到程序执行的各种情况。 场景法是通过运用场景(从用户使用的角度)来对系统的功能点或业务流程进行覆盖,从而提高测试效果的一种测试用例设计方法方法。 用事件来触发控制流程的, 如:我们申请一个项目, 需先提交审批单据, 再由部门经理审批, 审核通过后由总经理来最终审批, 如果部门经理审核不通过,就直接退回。 多个事件的依次触发形成事件流。 场景法中把事件流分为基本流和备用流, 基本流指程序每个步骤都“正常”运作时所经过的执行路径。 备选流是程序执行可能经过,也可能不经过的路径,可以有多个,是基本流之外可选的或备选的情况,一般对应的是异常的事件流程。 程序规格: 用户在一个在线购物网站购物,需要成功登录到系统,选购后在线购买,在线上支付。支付成功后生成订单,完成购物。 1、根据说明,描述出程序的基本流及各项备选流。 2、根据基本流和各项备选流生成不同的场景。 场景1:基本流 场景2:基本流,备选流1 场景3:基本流,备选流2 场景4:基本流,备选流3 场景5:基本流,备选流4错误推测法 3、对每一个场景生成相应的测试用例。 设有一合法账号abc;密码为123;账户余额200。 基于经验和问题分析推测程序中可能存在的各种错误,有针对性的设计测试用例来对程序进行测试,这就是错误推测法。 例如,软件中常见的缺陷: 对输入数据没有限制和校验 网站页面执行出错时会将服务器的调试信息显示在页面上 对空数据表执行删除记录操作 重复删除记录 ... ... 给定一个测试需求集TR和一个满足所有测试需求的测试用例集T,如果从T中移除任意单个的测试用例会导致T不再满足所有的测试需求,那么T就是极小的(没有冗余的)。 给定一个测试需求集TR和一个满足所有测试需求的测试用例集T,如果不存在满足所有测试需求的更小的测试用例集,那么T就是最小的。 (举例如下: 当我们考虑一个简单的登录功能时,我们可以用来说明这两个概念。 假设我们有以下测试需求: 现在我们有一个测试用例集T,其中包含以下测试用例: T = {测试用例1, 测试用例2, 测试用例3, 测试用例4} 假设测试用例1对应测试需求1,测试用例2对应测试需求2,以此类推。 现在我们来看看极小测试用例集和最小测试用例集的区别: 极小测试用例集:如果我们从T中移除任意一个测试用例,比如测试用例1,那么T就无法满足所有的测试需求,因为我们无法验证测试需求1。因此,T是极小的,因为没有多余的测试用例。 最小测试用例集:假设我们找到了另一个测试用例集T',它只包含测试用例1和测试用例4,但是可以满足所有的测试需求。这样,T'就是一个更小的测试用例集,它也满足所有的测试需求。因此,T不是最小的,因为存在更小的测试用例集T'可以满足所有的测试需求。 希望这个例子能够帮助你理解极小测试用例集和最小测试用例集的区别。 ) 给定一个测试需求集TR和一个测试用例集T,T满足TR中的需求数和TR的需求总数的比例,称为覆盖率。 测试准则C1包含测试准则C2,当且仅当满足C1的所有测试用例集也满足C2 给定一个测试需求集TR和一个测试用例集T,T满足TR中的需求数和TR的需求总数的比例,称为覆盖率。 例如,判定(即分支)覆盖率: 被测试到的判定分支数 / 判定分支总数代码走查
代码审查与代码走查的区别
静态结构分析
白盒测试
(动态)白盒测试方法:
控制流分析和数据流分析(了解):
if:
while:
do-while
for
break和continue
switch语句
例题:
基本路径与主路径测试:
圈复杂度
路径:
简单路径
主路径
简单路径:只有一个节点:[1],[2],[3],[4] 有两个节点:[1,2],[1,3],[2,4],[3,4],[4,1] 有三个节点:[1,2,4],[1,3,4],[2,4,1],[3,4,1],[4,1,2],[4,1,3] 有四个节点:[1,2,4,1],[1,3,4,1],[2,4,1,2],[2,4,1,3],[3,4,1,2],[3,4,1,3],[4,1,2,4],[4,1,3,4]基路径
测试路径:
主路径的概念:
基本路径应满足:
2)该路径至少包含一条其它基本路径没有包含的边。覆盖:
基本路径覆盖:
求主路径:
主路径覆盖 :
求覆盖所有主路径的测试路径集
逻辑覆盖法:
1.语句覆盖
2.判定覆盖:
3.条件覆盖
4.条件/判定覆盖
5. 条件组合覆盖
例题:
(A ∧ B) ∨ C
覆盖标准对比:
6.修正条件/判定覆盖(MC/DC!!
修正条件/判定覆盖(MC/DC覆盖)要求为:
例题:
如何求满足MC/DC的测试用例集?
7.路径覆盖
循环测试
测试基本循环
测试嵌套循环
测试串接循环
非结构循环的测试
程序插装
怎么插桩:
插装的作用:
补充:白盒测试方法运用示例
设计步骤
基本路径
逻辑覆盖——以分支-条件覆盖为例
循环测试
整合
变异测试
程序变异:
变异算子
算子类别:
变异测试定义:
基本思想:
变异体无法被杀死的原因
变异分数的计算
如何变异
变异测试的优缺点
黑盒测试
概念:
黑盒测试的优缺点
常用的方法和技术有:
等价类划分法
等价类
等价类划分
等价类组合
等价类测试的步骤
等价类划分测试举例
2.边界值分析法
边界值分析法选择测试用例的原则
边界值的组合
1、一般边界值:单缺陷假设、只考虑有效值。
2、一般最坏情况边界值:多缺陷假设、只考虑有效值。
3、健壮边界值:单缺陷假设、考虑有效值和无效值
4、健壮最坏情况边界值:多缺陷假设、考虑有效值和无效值
例题1:
例题2:
决策表法
例题:
决策表的分类
决策表的建立步骤
1.列出所有的条件桩和动作桩,确定规则的条数 例如
2、填入条件的不同取值组合;
3、填入具体动作,得到初始判定表;
4、化简,合并一些具有相同动作的相似规则。
决策表对我们的软件测试有什么用呢?
练习1:
练习2
例3
小结
因果图法
定义
优点
画法:
采用因果图法设计测试用例的步骤,
应用因果图判定表的思想设计测试用例。
组合测试
概念
组合测试的数学基础
正交表:
利用正交表实现组合测试
正交表示例
测试步骤:
正交表如何构造、构造算法?(如何选择合适正交表,
正交表存在如下问题:
例子:
例子2
例3:
成对测试(pairwise coverage)
组合测试与成对测试的区别
正交实验法和组合测试:
蜕变测试
蜕变测试的出发点 :
蜕变测试的基本理论
蜕变测试(metamorphic testing)
蜕变测试过程
蜕变测试的例子
场景法
事件流:
例题:
错误推测法
覆盖:
极小测试用例集:
最小测试用例集:
覆盖程度:
准则包含:
覆盖率: