07 基于结构的测试技术

Posted on Wed, 25 Dec 2024 17:06:43 +0800 by LiangMingJian


1.静态测试

1.1 静态测试的定义

  • 静态测试是指在不运行程序的情况下对软件或代码进行测试,主要包括代码审查、静态分析和测试设计等活动。
  • 静态测试主要用于发现代码中潜在的问题,如代码逻辑错误、语法错误、安全漏洞、性能问题等,以提高软件质量和可靠性。
  • 静态测试中,评审或审查是对软件缺陷或错误的一种预防措施,执行静态测试有利于提高软件质量, 减少后期修复成本,提高开发效率,改善代码可维护性,以及提高软件安全性。

1.2 静态测试的类型

  • 代码走查:一个开发人员与架构师讨论代码的过程,目的是交换有关代码是如何书写的思路等。
  • 桌面检查:一种比较古老的人工查找错误的方法,可以理解为代码编写人员对照错误列表来对程序进行推演,测试数据的过程。此过程一般由单人完成。
  • 代码审查:对计算机源代码系统化地审查,其目的是在找出及修正在软件开发初期未发现的错误,提升软件质量及开发者的技术。
  • 静态分析:使用自动化工具对代码进行扫描和分析,检查代码中是否存在潜在的问题,如安全漏洞、内存泄漏、死代码、重复代码等。
  • 测试设计:在软件开发早期,对软件需求和规格说明书进行分析和评审,以确定测试策略、测试用例、测试环境等。测试设计可以帮助开发人员更好地理解软件需求和规格,从而提高测试效率和软件质量。
  • 静态度量:通过对代码进行统计和分析,评估软件质量和可维护性,提供代码复杂度、耦合度、内聚度、代码行数、注释率等指标,从而帮助开发人员更好地理解和管理代码。

1.3 静态测试的内容

  • 源程序文档化检查:包括符号的命名,程序的注释等内容的检查
  • 数据说明检查:包括数据说明次序,语句中变量顺序的检查
  • 程序结构检查:程序应采用基本的控制结构,避免不必要的转移控制等
  • 输入输出方式:程序应当明确标注输入输出方式
  • 代码注释率:程序中注释应当不小于代码行数的 20%

1.4 静态测试的度量

  • 代码质量:包括代码复杂度、注释率、重复代码率、代码规范符合度等指标。
  • 缺陷检测率
  • 测试覆盖率
  • 反馈时间
  • 安全性和可维护性

1.5 静态分析

1.5.1 概念

  • 静态分析提供了一种机制,可以审查代码结构、控制流和数据流,检测潜在的可移植性和可维护性的问题,计算适当的软件质量测度。
  • 静态分析的内容包括:
    • 控制流分析:控制流分析方法是通过生存程序的有向控制流图来对代码进行分析。可发现逻辑判断和结构方面的缺陷,不能测试性能。
    • 数据流分析:是用来测试变量设置点和使用点之间的路径。可发现变量定义和使用方面的缺陷。
    • 接口一致性分析:可以检查模块之间接口的一致性和模块与外部数据库之间接口的一致性。
    • 表达式分析:可以发现表达式中出现的错误。

1.6.1 控制流图

  • 控制流图是描述程序控制流的一种图示方法,使用节点和控制流来进行描述,常用于静态测试中代码的结构化检测,控制流分析。
  • 节点代表基本程序块,可以是一个单独的判断或循环语句,也可以是一段顺序执行的程序段。
  • 区域代表一组节点与其相连的边共同构成的部分。

1.6.2 McCabe(圈)复杂度

  • 程序的 McCabe (圈)复杂度,又称环路复杂度,一般用圈复杂度 V(G) 来描述。
  • 圈复杂度用来衡量一个程序模块所包含判定结构的复杂程度,数量上表现为独立路径(独立路径 / 线性无关的基本路径是指与其他已有路径至少有一个新处理语句或一个新判断的程序通路,即新路径不能由旧路径截取组合)的条数。同时,圈复杂度也是程序中每个可执行语句至少执行一次所需测试用例数。
  • 控制流图边的数量 - 节点的数量 + 2
  • 控制流图判定节点的数量 + 1
  • 控制流图中的区域数(主要图形外的内容也应记作一个区域)

1.6.3 基本圈复杂度

  • 基本圈复杂度 EV(G),用来衡量程序的非结构化程度。
  • 基础圈复杂度高意味着,程序非结构化程度高,难以模块化和维护。
  • 当基本复杂度为 1,这个模块是充分结构化的。
  • 当大于 1 而小于圈复杂度时,这个模块是部分结构化。
  • 当等于圈复杂度时,这个模块是完全非结构化。
  • 基础圈复杂度的计算方法是将控制流图中的结构化部分简化成节点(保留起点终点,聚合中间过程),计算简化后控制流图的圈复杂度就是基本复杂度。

2.动态测试

2.1 逻辑覆盖法设计用例

  • 语句覆盖 SC:最弱的逻辑覆盖,每条语句至少被执行一次
  • 判定(分支)覆盖 DC:使每个判定至少获得一次真值和一次假值,或使每一个取真分支和取假分支至少执行一次。常规来说只有if被称为判定语句
    • 示例: 假设 A、B 为布尔变量,对于逻辑表达式( A && B || C ),需要 2 个测试用例才能完成判定覆盖(DC)。
  • 条件覆盖 CC:使每个判定中的每个逻辑条件可能值至少满足一次,如if((x>2)&&(y<10)),不考虑整个判定的可能值
  • 条件判定覆盖 CDC:使每个判定中的所有条件可能取值至少执行一次,同时,所有判定的可能结果至少执行一次
  • 条件组合(多条件)覆盖 MCC:使每个判定中逻辑条件的各种可能组合都出现一次,条件组合覆盖的用例数是 2^n,n 是判定中的逻辑条件
    • 示例:对于逻辑表达式((a||(b&c))||(c&&d)),因为&为位运算,不是逻辑条件(同理 | 也是位运算),所以判定中的逻辑条件为:a、b&c、c、d,即需要 2^4 个测试用例才能完成条件组合覆盖
  • 修正条件判定覆盖 MCDC:要求在一个程序中每一种输入输出至少得出现一次,在程序中的每一个条件必须产生所有可能的输出结果至少一次,并且存在用例使得每一个判定中的每一个条件能够独立影响一个判定的输出,即在其他条件不变的前提下仅改变这个条件的值,而使判定结果改变,其测试用例数一般为条件数+1~条件数*2的范围内
  • 路径覆盖 PC:覆盖程序中所有可能路径

2.2 逻辑覆盖间关系

SCDCCCCDCMCCMCDCPC
SC
DCY
CC??
CDCYYY
MCCYYYY
MCDCYYYY?
PCYYYY?Y
  • 竖轴内容决定横轴内容
  • 如 100 % CC 不一定满足 100% DC
  • 如 100% DC 一定满足 100% SC