『软件测试4』一文详解四大典型的白盒测试方法(一)

简介: 笔记

1.png软件测试——详解白盒测试基本概念,四种白盒测试方法



在上一篇文章中,我们讲到了黑盒测试。黑盒测试相较于白盒测试来说比较简单,不需要了解程序内部的代码,与软件的内部实现无关;而白盒测试就像是一个透明的盒子,它需要测试人员利用程序内部的逻辑结构来设计测试用例,相对于黑盒测试来说会难一些。

在下面的这篇文章中,我们将讲解白盒测试的基本概念,以及四大常用的白盒测试方法


一、白盒测试基本概念



1、白盒测试的定义


白盒测试又称为结构测试逻辑驱动测试,它是把测试对象看成一个透明的盒子,它允许测试人员利用程序内部的逻辑结构设计测试用例,对程序所有逻辑路径进行测试。

2.png


2、白盒测试的测试对象


白盒测试的测试对象是基于被测试程序的源代码,而不是软件的需求规格说明书。

使用白盒测试方法时,测试人员必须全面了解程序内部逻辑结构,检查程序的内部结构,从检查程序的逻辑着手,对相关的逻辑路径进行测试,最后得出测试结果。


3、白盒测试的原则


采用白盒测试方法必须遵循以下原则:

  • 保证一个模块中的所有独立路径至少被测试一次
  • 对所有的逻辑判定均需测试取真和取假两种情况。
  • 在上下边界及可操作范围内运行所有循环。
  • 检查程序的内部数据结构,保证其结构的有效性。


4、白盒测试的分类


白盒测试方法有两大类:静态测试方法动态测试方法

静态测试: 不要求在计算机上实际执行所测试的程序,主要以一些人工的模拟技术对软件进行分析和测试,如代码检查法静态结构分析法等;

动态测试: 是通过输入一组预先按照一定的测试准则构造实际数据来动态运行程序,达到发现程序错误的过程。白盒测试中的动态分析技术主要有逻辑覆盖法基本路径测试法。( ★ ★ ★ )

下面将对两种白盒测试方法进行讲解。


二、静态白盒测试



1、代码检查法


(1)代码审查的定义

代码审查(Code Review)是指对计算机源代码进行系统地审查,找出并修正在软件开发初期未发现的错误,提升软件质量及开发者的技术。


(2)代码审查的目的

代码审查的目的是为了产生合格的代码检查源程序编码是否符合详细设计的编码规定,确保编码与设计的一致性和可追踪性。


(3)代码审查的方法

代码审查包括桌面检查代码审查走查

1)桌面检查(程序员自己检查)

这是一种传统的检查方法,由程序员检查自己编写的程序。程序员在程序通过编译之后,对源程序代码进行分析、检查,并补充相关的文档,目的是发现程序中的错误。

2)代码审查(审查小组通过读程序和对照错误检查表进行检查)

代码审查是由若干程序员测试员组成一个审查小组,通过阅读、讨论和争议,对程序进行静态分析的过程。具体过程如下:

第一步, 小组负责人提前把设计规格说明书、控制流程图、程序文本及有关要求、规范等分发给小组成员,作为审查的依据。小组成员在充分阅读这些材料后,进入审查的下一步。

第二步,召开程序审查会。 每个成员将所发材料作为审查依据,但是由程序员讲解程序的结构、逻辑和源程序。在此过程中,小组成员可以提出自己的疑问;程序员在讲解自己的程序时,也能发现自己原来没有注意到的问题。

注意: 在进行代码检查前应准备好需求文档、程序设计文档、程序的源代码清单、代码编码标准、代码缺陷检查表和流程图等。

3)走查 (审查小组需要准备有代表性的测试用例沿程序逻辑运行)

走查与代码审查基本相同,其过程分为两步:

第一步: 把材料先发给走查小组每个成员,让他们认真研究程序。

第二步: 开会。

与代码审查不同的是,让审查小组成员“充当”计算机,即首先由测试组成员为所测程序准备一批有代表性的测试用例,提交给走查小组。走查小组开会,集体扮演计算机角色,让测试用例沿着程序的逻辑运行一遍,随时记录程序的踪迹,提供给最后阶段的分析和讨论使用。


(4)代码检查规则

在代码检查中,需要依据被测试软件的特点,选用适当的标准规则规范

3.png


(5)代码检查项目


  • 目录文件组织
  • 检查函数
  • 数据类型及变量
  • 检查条件判断语句
  • 检查循环体制
  • 检查代码注释
  • 桌面检查
  • 其他检查


2、静态结构分析法


(1)定义

在静态结构分析法中,测试人员通常通过使用测试工具分析程序源代码的系统结构、数据结构、数据接口、内部控制逻辑等内部结构,生成函数调用关系图模块控制流图内部文件调用关系图等各种图形、图表,清晰地标识整个软件的组成结构。


(2)目的


通过分析这些图表,包括控制流分析、数据流分析、接口分析、表达式分析等,使其便于阅读与理解,然后可以通过分析这些图表,检查软件有没有存在缺陷或错误。


(3)静态结构分析的两种方法


1)通过生成各种图表,来帮助对源程序的静态分析

常用的各种引用表主要有:标号交叉引用表;变量交叉引用表;子程序(宏、函数)引用表; 等价表;常数表。

常用的各种关系图、控制流图主要有:

①函数调用关系图: 列出所有函数,用连线表示调用关系,通过应用程序各函数之间的调用关系展示了系统的结构。

②模块控制流图:许多结点和连接结点的边组成的图形,其中每个结点代表一条或多条语句,边表示节点间的控制流向,用于显示函数的内部逻辑结构。(★ ★ ★ )

2) 错误静态分析

静态错误分析主要用于确定在源程序中是否有某类错误或“危险”结构

①类型和单位分析: 数据类型的错误和单位上的不一致。

②引用分析: 引用异常,变量赋值先引用,或赋值未引用。

③表达式分析: 表达式错误,不正确使用括号,数组下标越界等。

④接口分析: 模块的接口,参数的一致性。


三、动态白盒测试



1、逻辑覆盖法


(1)定义


逻辑覆盖是以程序内部的逻辑结构为基础来设计测试用例的测试技术,通过对程序内部的逻辑结构的遍历来实现程序的覆盖。它属于白盒测试中动态测试技术之一。


(2)6种逻辑覆盖方法


从覆盖源程序语句的详尽程度分析,逻辑覆盖包括以下6种覆盖标准:

  • 语句覆盖(SC);
  • 判定覆盖(DC);
  • 条件覆盖(CC);
  • 判定-条件覆盖(CDC);
  • 条件组合覆盖(MCC);
  • 路径覆盖。

接下来将对这6种逻辑覆盖方法进行一一讲解。

1)语句覆盖(SC)

①定义: 语句覆盖(Statement Coverage)的含义就是设计足够的测试用例,使得被测程序中每条语句至少执行一次。又称行覆盖、段覆盖、基本块覆盖,它是最常见的覆盖方式。

②例子展示:chestnut:

Question:

如下C语言程序语句和对应的程序流程图:

int function(int x,int y,int z)   
{
  if(y>1 && z==0)           
   {
      x=(int)(x/y)
   }
  if(y==2 || x>1)
   {
     x=x+1
   }
 return x;
}
复制代码

4.png

请使用语句覆盖来为该程序设计测试用例。

Answer:

为了使每条语句都能够至少执行一次,我们可以构造以下测试用例:

输入: x=4 , y=2 , z=0

执行路径为:sacbed

语句覆盖虽然可以测试执行语句是否被执行到,但却无法测试程序中存在的逻辑错误。因此,语句覆盖是一种弱覆盖

例如,如果上述程序中的第一个逻辑判断符号 “&&” 误写了 “||” ,使用测试用例同样可以覆盖 sacbed 路径上的全部执行语句,但却无法发现错误。同样,如果第二个逻辑判断符号 “||” 误写了 “&&” ,使用同样的测试用例也可以执行 sacbed 路径上的全部执行语句,但却无法发现上述逻辑错误。

③语句覆盖的目的:

语句覆盖的目的是测试程序中的代码是否被执行,它只测试代码中的执行语句,这里的执行语句不包括头文件、注释、空行等。

语句覆盖在多分支的程序中,只能覆盖某一条路径,使得该路径中的每一个语句至少被执行一次,但不会考虑各种分支组合情况

2)判定覆盖(DC)

①定义:

  • 判定覆盖(Decision Coverage)又称为分支覆盖,其原则是设计足够的测试用例,使得程序中每个判定语句的取真和取假分支至少被执行一次
  • 除了双值的判定语句外,还有多值判定语句,如case语句,因此判定覆盖更一般的含义是:使得每一个判定获得每一种可能的结果至少一次

②例子展示:chestnut:

Question:

如下C语言程序语句和对应的程序流程图:

int function(int x,int y,int z)   
{
  if(y>1 && z==0)           
   {
      x=(int)(x/y)
   }
  if(y==2 || x>1)
   {
     x=x+1
   }
 return x;
}
复制代码

5.png

请使用判定覆盖来为该程序设计测试用例。

Answer:

以上述代码为例,构造以下测试用例即可实现判定覆盖标准:

输入:① x=1,y=3,z=0 ,执行路径为 sacbd

(判断的结果分别为T,F

输入:②  x=3,y=1,z=1 ,执行路径为 sabed

(判断的结果分别为F,T

上述两组测试用例不仅满足了判定覆盖,而且满足了语句覆盖,从这一点可以看出判定覆盖比语句覆盖更强一些。所以只要满足了判定覆盖就一定满足语句覆盖,反之则不然

判定覆盖仍然具有和语句覆盖一样无法发现逻辑判断符号 “&&” 误写了 “||” 的逻辑错误。

判定覆盖仅仅判断判定语句执行的最终结果而忽略每个条件的取值,所以也属于弱覆盖

3)条件覆盖(CC)

①定义:

条件覆盖(Condition Coverage)指的是设计足够的测试用例,使判定语句中的每个逻辑条件取真值与取假值至少出现一次

例如,对于判定语句 if(a>1 OR c<0) 中存在 a>1、c<0 两个逻辑条件,设计条件覆盖测试用例时,要保证 a>1、c<0 的“真”、“假”值至少出现一次。

②例子展示:chestnut:

Question:

如下C语言程序语句和对应的程序流程图:

int function(int x,int y,int z)   
{
  if(y>1 && z==0)           
   {
      x=(int)(x/y)
   }
  if(y==2 || x>1)
   {
     x=x+1
   }
 return x;
}
复制代码

6.png

请使用条件覆盖来为该程序设计测试用例。

Answer:

要使程序中每个判断的每个条件都至少取真值、假值一次,我们可以构造以下测试用例:

输入:① x=1,y=2,z=0 ,执行路径为 sacbed

(条件的结果分别为TTTF

输入:② x=2,y=1,z=1 ,执行路径为 sabed

(条件的结果分别为FFFT

从条件覆盖的测试用例可知,使用2个测试用例就达到了使每个逻辑条件取真值与取假值都至少出现了一次,但从测试用例的执行路径来看,条件分支覆盖的状态下仍旧不能满足判定覆盖,即没有覆盖 bd 这条路径。相比于语句覆盖与判定覆盖,条件覆盖达到了逻辑条件的最大覆盖率,但却不能保证判定覆盖。

4)判定-条件覆盖(CDC)

①定义:

  • 要求设计足够的测试用例,使得判定语句中所有条件的可能取值至少出现一次,同时,所有判定语句的可能结果也至少出现一次
  • 例如,对于判定语句 if(a>1 AND c<1) ,该判定语句有 a>1、c<1 两个条件,则在设计测试用例时,要保证 a>1、c<1 两个条件取“真”、“假”值至少一次,同时,判定语句 if(a>1 AND c<1) 取“真”、“假”也至少出现一次。

②例子展示:chestnut:

Question:

如下C语言程序语句和对应的程序流程图:

int function(int x,int y,int z)   
{
  if(y>1 && z==0)           
   {
      x=(int)(x/y)
   }
  if(y==2 || x>1)
   {
     x=x+1
   }
 return x;
}
复制代码

7.png

请使用判定条件覆盖来为该程序设计测试用例。

Answer:

为满足判定-条件覆盖原则,我们可以构造以下测试用例:

输入:① x=4,y=2,z=0 ,覆盖路径:sacbed

(判断的结果分别为TT,条件的结果分别为:TTTT

输入:②  x=1,y=1,z=1 ,覆盖路径:sabd

(判断的结果分别为FF,条件的结果分别为:FFFF

判定-条件覆盖满足了判定覆盖准则条件覆盖准则,弥补了二者的不足。但是判定-条件覆盖不一定比条件覆盖的逻辑更强。

③判定-条件覆盖的缺点: 没有考虑条件的组合情况。

5)条件组合覆盖(MCC)

①定义:

条件组合(Multiple Condition Coverage)指的是设计足够的测试用例,使得每个判定中条件的各种可能组合都至少执行一次。满足了判定覆盖、条件覆盖、判定-条件覆盖准则。

②例子展示:chestnut:

Question:

如下C语言程序语句和对应的程序流程图:

int function(int x,int y,int z)   
{
  if(y>1 && z==0)           
   {
      x=(int)(x/y)
   }
  if(y==2 || x>1)
   {
     x=x+1
   }
 return x;
}
复制代码

8.png

请使用条件组合覆盖来为该程序设计测试用例。

Answer:

为满足条件组合覆盖原则,我们可以构造以下测试用例:

输入:① x=4,y=2,z=0 ,覆盖路径: sacbed(条件的结果分别为:TTTT

输入: ② x=1,y=2,z=1,覆盖路径: sabed(条件的结果分别为:TFTF

输入:③ x=2,y=1,z=0 ,覆盖路径: sabed(条件的结果分别为:FTFT

输入: ④ x=1,y=1,z=1,覆盖路径: sabd(条件的结果分别为:FFFF

由于这4个条件每个条件都有取“真”、“假”两个值,因此所有条件结果的组合有24=16种。但是,当一个程序中判定语句较多时,其条件取值的组合数目也较多。需要设计的测试用例也会增加,这样反而会使测试效率降低。

6)路径覆盖

①定义:

路径覆盖指的是设计足够的测试用例,使得程序中的每一条可能组合的路径都至少执行一次

②例子展示:chestnut:

Question:

如下C语言程序语句和对应的程序流程图:

int function(int x,int y,int z)   
{
  if(y>1 && z==0)           
   {
      x=(int)(x/y)
   }
  if(y==2 || x>1)
   {
     x=x+1
   }
 return x;
}
复制代码

9.png

请使用路径覆盖来为该程序设计测试用例。

Answer:

为满足路径覆盖原则,我们可以构造以下测试用例:

输入:① x=4,y=2,z=0 ,覆盖路径:sacbed

(判定的结果分别为:TT

输入:② x=1,y=2,z=1,覆盖路径: sabed

(判定的结果分别为:FT

输入:③ x=1,y=3,z=0 ,覆盖路径: sacbd

(判定的结果分别为:TF

输入:④ x=1,y=1,z=1 ,覆盖路径: sabd

(判定的结果分别为:FF


相关文章
|
16天前
|
运维 Ubuntu 测试技术
自动化运维的利剑:Ansible在配置管理中的应用软件测试的艺术:探索性测试的深度与广度
【8月更文挑战第27天】 在数字化浪潮中,高效的运维工作是支撑企业IT系统稳定运行的关键。Ansible,作为一款简易而强大的自动化运维工具,正逐渐成为IT专业人士的新宠。本文将通过浅显易懂的语言和生动的案例,带你了解Ansible的核心概念、安装步骤、基础命令以及它在配置管理中的实际应用。我们的目标是让初学者能够轻松上手Ansible,同时为有经验的运维工程师提供一些实用的技巧和思路。
|
15天前
|
安全 测试技术
软件测试的艺术:探索性测试的奥秘
【8月更文挑战第28天】在软件开发的宇宙中,测试是那颗指引航船安全抵达目的地的北极星。探索性测试(Exploratory Testing, ET)作为一种灵活而富有创造性的测试实践,它如同艺术家的画笔,描绘出软件质量的全貌。本文将带你领略探索性测试的魅力,从其哲学到实操技巧,再到如何与自动化测试和谐共存,我们将一同走进这个充满未知与惊喜的软件测试领域。
|
16天前
|
SQL 安全 测试技术
网络安全的屏障与钥匙:漏洞防护与加密技术解析软件测试的艺术:探索性测试的力量
【8月更文挑战第27天】在数字时代的海洋中,网络安全是保护我们数据资产的灯塔和堤坝。本文将深入浅出地探讨网络安全领域的关键要素——安全漏洞、加密技术以及不可或缺的安全意识。通过实际案例分析,我们将了解如何识别和修补潜在的安全漏洞,掌握现代加密技术的工作原理,并培养起一道坚固的安全防线。文章旨在为读者提供实用的知识和技能,以便在日益复杂的网络环境中保持警惕,确保个人及组织信息的安全。
|
6天前
|
芯片
LDO的原理及测试方法
一、基本结构 这是LM317芯片的核心,这个电路单元称为Bandgap Reference带隙基准源。属于模拟集成电路中的经典电路结构。 LDO拓扑结构图 常见的基本结构 利用VBE的负温度系数,而VT是正温度系数,正负温度系数抵消就的得到稳定的基准参考电压了(三极管的方程VBE=VT*In(lC/IS))。 二、测试意义 了解集成电路的内部结构对测试有意义么? 1、了解内部结构,才能更好的理解测试原理或者设计测试方案2、可以学习提升对电路结构的理解能力。 针对LM317,了解了内部简单原理,可以知道1、内部结构设计针对的是温度系数,因此可能受温度的影响,实际也是会受到温度的影
152 88
|
5天前
|
机器学习/深度学习 敏捷开发 大数据
软件测试的演变之旅:从传统方法到自动化革命
在数字时代的浪潮下,软件测试作为保障产品质量的关键一环,经历了从手工测试到自动化测试的重大转变。本文将探讨这一演变背后的驱动力、所面临的挑战以及未来的发展趋势,为读者揭示软件测试领域的深层次变革。
|
12天前
|
监控 测试技术 Python
软件测试的艺术与科学:探索测试自动化的奥秘
【8月更文挑战第30天】在软件开发的海洋中,测试是那把确保航船不偏离航线的罗盘。本文将带您一探究竟,从测试的基础到高级自动化策略,揭示如何通过代码和工具提升测试效率。准备好启航,因为我们将深入探讨软件测试的核心,以及如何利用自动化技术来优化您的测试流程。
13 4
|
12天前
|
物联网 测试技术 持续交付
软件测试的艺术与科学:探索自动化测试框架未来技术的融合与创新:探索区块链、物联网和虚拟现实的交汇点
【8月更文挑战第30天】在软件开发的海洋中,测试是确保航行安全不可或缺的灯塔。本文将带领读者揭开软件测试神秘的面纱,深入理解自动化测试框架的重要性和实现方法。通过实际案例,我们将一起探索如何构建高效、可靠的自动化测试系统,从而保障软件质量,提升开发效率。
|
15天前
|
测试技术
软件测试的艺术:探索性测试的力量
【8月更文挑战第27天】在软件测试领域,探索性测试(Exploratory Testing)是一种既自由又创造性的测试实践。它不依赖于事先编写的测试用例,而是鼓励测试人员发挥他们的直觉、经验和逻辑推理能力,去发现软件中可能隐藏的缺陷和问题。这种方法强调的是测试过程的灵活性和适应性,让测试更加贴近实际的用户场景和需求。探索性测试不仅能够提高测试效率,还能够促进测试人员之间的知识共享和协作。
|
9天前
|
测试技术 数据安全/隐私保护
软件测试的艺术:如何高效地编写测试用例
【9月更文挑战第2天】在软件开发的海洋中,测试用例是导航灯塔,指引着质量保障的航向。本文将带你航行于测试用例编写的技巧之海,从理解需求到设计思路,再到实际执行,我们将一起探索如何高效而精准地构建测试用例,确保软件的稳健与可靠。
20 0
|
11天前
|
测试技术 UED Python
探索软件测试的边界:自动化与手动测试的协同
【8月更文挑战第31天】 在追求效率和质量的软件生产中,自动化测试与手动测试的辩论从未停止。本文将通过实际案例,揭示二者如何相辅相成,共同构建更健壮的软件测试体系。我们将深入探讨自动化测试的优势、手动测试不可替代的角色以及它们如何在实际项目中协同工作,旨在为读者提供一种平衡的视角来看待软件测试的实践。