软件测试技术笔记2

软件测试技术笔记之二

开发人员测试

白盒测试

目录:

  1. 白盒测试方法

  2. 逻辑覆盖测试法

  3. 基本路径测试法

  4. 循环测试

  5. 测试用例数估算

黑盒测试与白盒测试的比较
黑盒测试:
  • 功能测试

  • 数据驱动测试

白盒测试:
  • 结构测试

  • 逻辑驱动测试

静态白盒测试

在不执行软件的条件下进行程序设计的审查

动态白盒测试(结构化测试)

检查代码观察运行状况

白盒测试主要方法:
  • 逻辑覆盖测试法

  • 基本路径测试法

  • 循环路径覆盖法

程序控制流图
image-20221114150337990 image-20221114150405720

image-20221205171154097

基本路径测试:
image-20221114150538456
静态符号执行
动态符号执行

以具体的数值作为输入,执行程序代码,在程序实际执行路径的基础上,用符号执行技术对路径进行分析,提取路径的约束表达式。

114日作业:静态分析\textcolor{red}{11月4日作业:静态分析}

image-20221114150729609

基于逻辑覆盖的测试方法

  • 语句覆盖(SC)

  • 判定覆盖(DC)

  • 条件覆盖(CC)

  • 判定-条件覆盖(CDC)

  • 条件组合覆盖(MCC)

语句覆盖(SC)
  1. 语句覆盖法的基本思想是设计若干测试用例,运行被测程序,使程序中的每个可执行语句至少被执行一次

  2. 如果是顺序结构,就是让测试从头执行到尾

  3. 如果有分支、条件和循环,需要利用判定覆盖、条件覆盖等方法,执行足够的测试覆盖全部语句

语句覆盖能发现一般语句的错误,但不能发现其中的逻辑错误。

判定(分支)覆盖(DC)
  1. 判定覆盖法的基本思想是设计若干用例,运行被测程序,使得程序中每个判断的取真分支和取假分支至少经历一次,即判断真假值均曾被满足。

  2. 一个判定代表着程序的一个分支,所以判定覆盖也被称为分支覆盖。

  3. 满足判定覆盖➔满足语句覆盖

image-20230218154524603

条件覆盖(CC)
  1. 条件覆盖的基本思想是设计若干测试用例,执行被测程序以后,要使每个判断中每个条件的可能取值至少满足一次

image-20230218154621783

image-20230218154715833

判定-条件覆盖(CDC)
  1. 判定-条件覆盖是判定和条件覆盖设计方法的交集,即设计足够的测试用例,使得判断条件中的所有条件可能取值至少执行一次,同时,所有判断的可能结果至少执行一次

image-20221114153711184

条件组合覆盖(MCC)
  1. 条件组合覆盖的基本思想是设计足够的测试用例,使得判断中每个条件的所有可能组合至少出现一次,并且每个判断本身的判定结果也至少出现一次

  2. 它与条件覆盖的差别是它不是简单地要求每个条件都出现“真”与“假”两种结果,而是要求让这些结果的所有可能组合都至少出现一次。

  3. 满足条件组合覆盖,一定满足判定覆盖、条件覆盖、条件判定组合覆盖

image-20221114154109637

基本路径测试法|基本路径覆盖(BPC)

基本路径覆盖的设计过程
  1. 依据代码绘制流程图(控制流图)

  2. 确定控制流图的圈复杂度(cyclomaticcomplexity )

  3. 确定线性独立路径的基本集合( basis set )

  4. 设计测试用例覆盖每条基本路径

圈复杂度就确定了基本集合中线性独立路径的数量。

同时注意基本集合不一定唯一

V(G)是一个上界

⭐️代码绘制流程图
1️⃣复合条件简化:

如果判断中的条件表达式是复合条件,即条件表达式是由一个或多个逻辑运算符(or, and, nor)连接的逻辑表达式,则需要改变复合条件的判断为一系列只有单个条件的嵌套的判断

1
2
3
4
5
6
7
8
9
10
11
12
13
# 原始代码
if a and b:
then x;
else:
then y;


#复合条件拆分
if a then:
if b then:
then x;
else:
then y;
🌊圈复杂度的计算

圈复杂度(Cyclomaticcomplexity): 代码逻辑复杂度的度量,提供了被测代码的路径数量。复杂度越高,出错的概率越大

image-20221116102954687

对于结点数量:包括起点和终点;所有终点只计算一次,多个return和throw算作一个节点

image-20221116103628905

实例:

image-20221116112006475

(控制流图)

image-20230218220149174

控制流图的几种结构:

img

关于流程图中的循环语句代码???
  1. 首先在绘制程序流程图的时候要将循环语句设计为判断结点

  2. 在计算圈复杂度时,由循环语句呈现的判断结点不算入下面公式的判断结点数目

☁️线性独立路径的基本集合

由基本集导出的测试用例,保证每行代码语句至少被执行一次基本集合不一定唯一

  1. 独立路径:至少引入一系列新的处理语句或条件的任何路径
  2. 基本集:由独立路径构成的集合
image-20221116103841143

习题:

image-20221116110336074 image-20221116110300651

以上流程图圈复杂度:9

⭐️分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//对于switch
switch(n)
{
case 1:
operation1;
break;
case 2:
operation2;
break;
default:
operation3;
break;
}
//可以转换为if-else的形式
if(n==1)
{operation1;}
else if(n==2)
{operation2;}
else
{operation3;}
//进一步地可以拓展为以下
if(n==1)
{operation1;}
else
{operation3;}
if(n==2)
{operation1;}
else
{operation3;}
/*由此可以看出存在两组if-esle结果,因此记判断节点数(或简单可预测节点数)为2*/

总结:基本路径测试并不是测试所有路径的组合,仅仅保证每条基本路径被执行一次\textcolor{red}{总结:基本路径测试并不是测试所有路径的组合,仅仅保证每条基本路径被执行一次}

测试用例覆盖每条基本路径

image-20221205173056291

小结:各覆盖之间的包含关系
image-20221116111415418

以上表示的是各种覆盖方法之间子集关系

白盒测试逻辑覆盖习题

image-20221116100341934

循环测试

目标:在循环内部及边界上执行测试

简单循环(迭代次数n)
  1. 完全跳过循环

  2. 只经过循环一次

  3. 经过循环两次

  4. 经过循环m(m < n )次

  5. 分别经过循环n-1, n, n+1 次

嵌套(Nested)循环
  1. 在最里面的循环完成前面所述的简单循环测试,同时设定外部循环的最小迭代次数

  2. 逐步向外循环进行

  3. 直到所有循环被测试

串行连接的循环
  1. 独立循环➔可以分别看成简单循环测试

  2. 依赖性循环➔可以看成是嵌套循环

循环化简

比较简单的小程序实现路径覆盖是可能做到的;如果程序中出现多个判断和多个循环,可能的路径数据急剧增长,以至于实现完全路径覆盖不可能做到。

  1. 对循环机制进行简化,舍掉一些次要因素,极大地减少路径数量,使得覆盖有限的路径成为可能。

  2. 循环化简,即限制循环的次数。无论循环的形式和实际执行循环体的次数多少,只考虑循环1次和0次两种情况,即进入循环和跳过循环两种情况。

最少测试用例数估算
  1. 顺序型——构成串行操作

  2. 选择型——构成分支操作

  3. 重复型——构成循环操作

image-20221116125307022

为简化问题,避免出现测试用例极多的组合爆炸,把构成循环操作的重复型结构用选择结构代替。即不指望测试循环体所有的重复执行,而是只对循环体检验一次。

串行分支路径计算方式:
image-20221116112145953 image-20221116112226435
复杂实例:
image-20221116112324286

上下层之间用乘法:

  1. 下层(8、9)判断有3条路径
  2. 上层(6、7)判断的总共3条路径*(2、3、4、5)判断总共5条路径=15条路径,再+(1)判断下Y情况的1条路径=>16条路径
  3. 最后上下相乘:3*16=48条路径

考试类型题:画流程图、覆盖\textcolor{red}{考试类型题:画流程图、覆盖……}

image-20221116113018608

问题1:(判断覆盖必须保证每个判定语句都分别取一次T和一次F

对于语句的100%判定覆盖

image-20230222190533112

以上表格中注意到的是year%100 == 0成立则year%4 == 0一定成立,因此year%4 == 0可以省略

image-20221123105856921

问题2:

V(G)=11

image-20221123110003672
image-20221123110303231 image-20221123110324263
image-20230222191357937

问题3:

11

线性无关路径与线性独立路径?

(每行代码至少被执行一次)

程序插桩

工具:JaCoCo

  • java程序覆盖信息收集工具
程序插桩类型

image-20221123111429595

变异测试

  1. 变异测试评价测试用例集S

  2. 评价之后生成缺陷检测能力更强的测试用例集合S+

相关参考:Mutation Testing(变异测试) - Weston233 - 博客园 (cnblogs.com)

CSU参考:(77条消息) 变异测试(mutation testing):一种评估测试用例集错误检测能力的方法_CSU迦叶的博客-CSDN博客_mutation test

变异体杀死
  1. 当原程序和变异程序存在差异时,测试用例检测到变异程序的缺陷,则变异程序被杀死;

  2. 当原程序和变异程序不存在差异时,测试用例检测不到变异程序的缺陷,则变异程序存活;

变异算子
  1. 运算符变异

  2. 数值变异

  3. 返回变异

  • ==定义 4(可杀除变异体)==若存在测试用例 t,在变异体 p′ 和原有程序 p 上的执行结果不一致, 则称该变异体 p′ 相对于测试用例集 T 是可杀除变异体。

  • 定义 5(可存活变异体) 若不存在任何测试用例t, 在变异体 p′ 和原有程序 p 上的执行结果不一致, 则称该变异体 p′ 相对于测试用例集 T 是可存活变异体。一部分可存活变异体通过设计新的测试用例可以转化成可杀除变异体, 剩余的可存活变异体则可能是等价变异体。本文对等价变异体定义如下。

  • ==定义 6 (等价变异体)==若变异体 p′ 与原有程序 p 在语法上存在差异, 但在语义上与 p 保持一致, 则称p′ 是 p 的等价变异体。

变异得分
image-20221123113534268

变异得分公式:

img

变异测试习题
image-20221123113908351 image-20221123113957994 image-20221123173112188

单元测试

定义

单元测试是对软件基本的组成单元进行独立的测试

单元测试可以由程序员自己完成也可以由专业人员完成

单元测试的目标
  • 目标:单元模块被正确编码

  • 信息能否正确地流入和流出单元

  • 在单元工作过程中,其内部数据能否保持其完整性

    • 包括内部数据的形式
    • 内容及相互关系不发生错误
    • 全局变量在单元中的处理和影响
  • 为限制数据加工而设置的边界处,能否正确工作

  • 单元的运行能否做到满足特定的逻辑覆盖

单元测试任务(5个任务)
  • 模块独立执行路径测试

    • 检查每一条独立执行路径的测试,并保证每条语句被至少执行一次。
  • 局部数据结构测试

    • 检查局部数据结构完整性。
      • 不正确或不一致的数据类型说明;使用尚未赋值或尚未初始化的变量;错误的初始值或错误的缺省值;变量名拼写错或书写错;不一致的数据类型。
  • 模块接口测试

    • 检查模块接口的正确性。
  • 单元边界条件测试

    • 检查临界数据处理的正确性。
  • 单元容错测试

    • 预设的各种出错处理是否正确有效。
单元测试最重要的手段——*静态测试*的运用
单元测试三部曲⭐️
  1. 互审

  2. 走审

  3. 评审

运行单元程序有时需要基于被测单元的接口,开发相应的驱动模块和桩模块

驱动模块(drive)
  • 对底层或子层模块进行测试所编写的调用这些模块的程序

  • 调用要测试的模块

桩模块(stub)
  • 对顶层或上层模块进行测试时所编写的替代下层模块的程序

  • 由被测试模块调用

image-20221128144227009

实例:

image-20221128144413388

集成测试

对概要设计书进行验证

集成测试模式
  1. 渐增式测试模式

    • 把下一个要测试的模块同已经测试好的模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合进来测试
    • 测试更彻底
    • 需要较多的机器时间
  2. 非渐增式测试模式

    • 先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序,如大棒模式。
    • 可以并行测试

大棒集成方法:先是对每一个子模块进行测试(单元测试阶段),然后将所有模块一次性的全部集成起来进行集成测试。

  • 适合在规模较小的应用系统中使用

两种模式比较:

image-20221128152034802

集成测试分析

组件之间存在显示/隐形相依性

相依性关系:关联、聚集、消息、调用、全局变量与公共数据。

获取相依性关系:

  • 结构分析

  • 接口分析

  • 模块分析

自顶向下法(Top-down Integration)

image-20221128160501703

自顶向下法需要许多插桩操作

自底向上法(Bottom-up Integration)

image-20221128160757817

需要驱动模块

混合策略(Modified Top-down Integration)
  • 混合法:对软件结构中较上层,使用的是“自顶向下”法;对软件结构中较下层,使用的是“自底向上
    法,两者相结合

  • image-20221128160856119

三明治集成方法(Sandwich Integration)

image-20221128161404502

将自顶向下和自底向上的集成方法有机地结合起来不需要写桩程序。因为在测试初自底向上集成已经验证了底层模块的正确性。

改善的三明治集成方法

image-20221128161458069

改进的三明治集成方法,不仅自两头向中间集成,而且保证每个模块得到单独的测试使测试进行得比较彻底

持续集成

通常系统集成都会采用持续集成的策略,软件开发中各个模块不是同时完成,根据进度将完成的模块尽可能早的进行集成,有助于尽早发现Bug,避免集成中大量Bug涌现。

面向对象的单元测试

面向对象的测试

  • 面向对象分析的测试

  • 面向对象设计的测试

  • 面向对象编程的测试

传统单元测试
  • 针对程序的函数、过程或完成某一特定功能的程序块

面向对象软件的单元测试
  • 测试类成员函数

image-20221207102510192

系统测试

  • 功能测试

  • 回归测试

  • 性能测试

    • 负载压力测试
    • 性能测试工具LoadRunner的初级使用
  • 其他非功能性测试

功能测试

单元功能测试

•保证所测试的每个独立的模块的功能正确,从输入条件和输出结果来判断是否满足程序的设计要求

系统功能测试

•考虑模块间的相互作用,考虑系统的应用环境

•衡量标准是实现产品规格说明书上所要求的功能

•特别地,模拟用户从头到尾(End-to-End,端到端)的业务测试,确保系统可以完成实现设计的功能,满足用户实际业务需求

功能测试要点

•每项功能符合实际要求

功能逻辑清楚,符合使用者习惯

•系统的各种状态按照业务流程而变化,并保持稳定

系统的界面清晰、美观

•菜单、按钮操作正常、灵活,能处理一些异常操作

•能接受正确的数据输入,对异常输入的容错处理

数据的输出结果准确,格式清晰,可以保存和读取

•程序安装、启动正常,有相应的提示框、错误提示等

•……

回归测试

  • 一旦程序某些区域被修改了,就可能影响其它区域,导致受影响的区域出现新的缺陷(回归缺陷)。

  • 回归测试是为了发现回归缺陷而进行的测试。

回归测试定义
  • 定义:对软件的新版本测试时,重复执行上一个版本测试时的用例

  • 回归测试可以在任何测试阶段进行。既有黑盒测试的回归,也有白盒测试的回归。

回归测试策略
  1. 再测试全部用例

  2. 基于风险选择测试

  3. 基于操作剖面选择测试

  4. 再测试修改的部分

  5. 更智能的选择方法

image-20221207105052116

性能测试

性能测试的基本流程(10步骤):

image-20230218195023212

性能测试用来保证产品发布后系统的性能能够满足用户需求

  1. 执行效率

  2. 资源占用

  3. 稳定性

  4. 安全性

  5. 兼容性

  6. 可扩展性

  7. 可靠性…

image-20221207105358428

性能测试(performance test)就是为了发现系统性能问题或获取系统性能相关指标而进行的测试。一般在真实环境特定负载(正常或峰值)条件下,通过工具模拟实际软件系统的运行及其操作,同时监控性能各项指标,最后对测试结果进行分析来确定系统的性能状况。

性能测试目标
  • 获取系统性能某些指标数据

  • 为了验证系统是否达到用户提出的性能指标

  • 发现系统中存在的性能瓶颈,优化系统的性能

    • 评价系统当前性能

    • 预测系统未来性能

    • 寻找瓶颈,优化性能

    • 寻找错误

性能测试类型

性能规划测试

  • 在多种特定的环境下,获得不同配置的系统的性能指标,从而决定在系统部署时采用什么样的软、硬件配置——预测系统未来性能

性能基准测试

  • 在系统标准配置下获得有关的性能指标数据,作为将来性能改进的基准线

容量测试

  • 可以看作性能的测试一种,因为系统的容量可以看作是系统性能指标之一

性能验证测试

  • 验证系统是否达到事先已定义的系统性能指标、能否满足系统的性能需求

image-20221207111214200
全生命周期性能评估

image-20221207111456089

产品生命周期中负载压力测试计划
  • 需求分析中充分关注负载压力性能

  • 在设计中得到负载压力性能指标

  • 开发阶段创建负载压力性能测试环境

  • 验收阶段在多等级范围内测试并调优

  • 运行阶段持续监控系统负载压力性能

性能测试需求和指标

用户对各项指标提出的明确需求;如果用户没有提出性能指标,则根据用户需求、测试设计人员的经验来设计各项测试指标。(需求+经验)

只有具备了清楚而量化的性能指标,性能测试才能开始实施。

主要的性能指标:

  • 服务器的各项指标(CPU、内存占用率等)

  • 后台数据库的各项指标

  • 网络流量

  • 响应时间

不同角度的关注点:

  • 最终用户的体验,如2-5-10原则

  • 商业需求,如“比竞争对手的产品好”

  • 技术需求,如CPU使用率不超过70%

  • 标准要求

  • 响应时间是用户的关注点;

  • 容量和数据吞吐量是(产品市场团队)业务处理方面的关注点;

  • 而系统资源占用率是开发团队的技术关注点。

性能的具体指标
  1. 数据传输的吞吐量(Transactions)

  2. 数据处理效率(Transactionspersecond)

  3. 数据请求的响应时间(Responsetime)

  4. 内存和CPU使用率

  5. 连接时间(ConnectTime)、发送时间(SentTime)

  6. 处理时间(ProcessTime)、页面下载时间

  7. 第一次缓冲时间

  8. 每秒(SSL)连接数

  9. 每秒事务总数、每秒下载页面数

  10. 每秒点击次数、每秒HTTP响应数

  11. 每秒重试次数

实例参考

image-20221207112712113

负载压力测试|性能测试的重要组成部分

负载压力测试,在一定约束条件下测试系统所能承受的并发用户量运行时间数据量,以确定系统能承受的最大负载压力。

在一种需要反常(如长时间的峰值)数量、频率或资源的方式下,执行可重复的负载测试,以检查程序对异常情况的抵抗能力,找出性能瓶颈或其它不稳定性问题。

负载压力测试类型
  • 并发性能测试(重点)

  • 疲劳强度测试

  • 大数据量测试

非功能性测试

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2024 Guijie Wang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信