在这篇文章中我们将讲解白盒测试的基本概念以及四大常用的白盒测试方法。一、白盒测试基本概念1、白盒测试的定义白盒测试又称为结构测试或逻辑驱动测试它是把测试对象看成一个透明的盒子它允许测试人员利用程序内部的逻辑结构设计测试用例对程序所有逻辑路径进行测试。2、白盒测试的测试对象白盒测试的测试对象是基于被测试程序的源代码而不是软件的需求规格说明书。使用白盒测试方法时测试人员必须全面了解程序内部逻辑结构检查程序的内部结构从检查程序的逻辑着手对相关的逻辑路径进行测试最后得出测试结果。3、白盒测试的原则采用白盒测试方法必须遵循以下原则保证一个模块中的所有独立路径至少被测试一次。对所有的逻辑判定均需测试取真和取假两种情况。在上下边界及可操作范围内运行所有循环。检查程序的内部数据结构保证其结构的有效性。4、白盒测试的分类白盒测试方法有两大类 静态测试方法和动态测试方法。静态测试不要求在计算机上实际执行所测试的程序主要以一些人工的模拟技术对软件进行分析和测试如代码检查法、静态结构分析法等动态测试是通过输入一组预先按照一定的测试准则构造实际数据来动态运行程序达到发现程序错误的过程。白盒测试中的动态分析技术主要有逻辑覆盖法和基本路径测试法。 ★ ★ ★ 下面将对两种白盒测试方法进行讲解。二、静态白盒测试1、代码检查法1代码审查的定义代码审查Code Review是指对计算机源代码进行系统地审查找出并修正在软件开发初期未发现的错误提升软件质量及开发者的技术。2代码审查的目的代码审查的目的是为了产生合格的代码检查源程序编码是否符合详细设计的编码规定确保编码与设计的一致性和可追踪性。3代码审查的方法代码审查包括桌面检查、代码审查和走查。1桌面检查程序员自己检查这是一种传统的检查方法由程序员检查自己编写的程序。程序员在程序通过编译之后对源程序代码进行分析、检查并补充相关的文档目的是发现程序中的错误。2代码审查审查小组通过读程序和对照错误检查表进行检查代码审查是由若干程序员和测试员组成一个审查小组通过阅读、讨论和争议对程序进行静态分析的过程。具体过程如下第一步小组负责人提前把设计规格说明书、控制流程图、程序文本及有关要求、规范等分发给小组成员作为审查的依据。小组成员在充分阅读这些材料后进入审查的下一步。第二步召开程序审查会。每个成员将所发材料作为审查依据但是由程序员讲解程序的结构、逻辑和源程序。在此过程中小组成员可以提出自己的疑问程序员在讲解自己的程序时也能发现自己原来没有注意到的问题。注意在进行代码检查前应准备好需求文档、程序设计文档、程序的源代码清单、代码编码标准、代码缺陷检查表和流程图等。3走查 审查小组需要准备有代表性的测试用例沿程序逻辑运行走查与代码审查基本相同其过程分为两步第一步把材料先发给走查小组每个成员让他们认真研究程序。第二步开会。与代码审查不同的是让审查小组成员“充当”计算机即首先由测试组成员为所测程序准备一批有代表性的测试用例提交给走查小组。走查小组开会集体扮演计算机角色让测试用例沿着程序的逻辑运行一遍随时记录程序的踪迹提供给最后阶段的分析和讨论使用。4代码检查规则在代码检查中需要依据被测试软件的特点选用适当的标准与规则规范。5代码检查项目目录文件组织检查函数数据类型及变量检查条件判断语句检查循环体制检查代码注释桌面检查其他检查2、静态结构分析法1定义在静态结构分析法中测试人员通常通过使用测试工具分析程序源代码的系统结构、数据结构、数据接口、内部控制逻辑等内部结构生成函数调用关系图、模块控制流图、内部文件调用关系图等各种图形、图表清晰地标识整个软件的组成结构。2目的通过分析这些图表包括控制流分析、数据流分析、接口分析、表达式 分析等使其便于阅读与理解然后可以通过分析这些图表检查软件有没有存在缺陷或错误。3静态结构分析的两种方法1通过生成各种图表来帮助对源程序的静态分析常用的各种引用表主要有①标号交叉引用表②变量交叉引用表③子程序宏、函数引用表④等价表⑤常数表。常用的各种关系图、控制流图主要有①函数调用关系图列出所有函数用连线表示调用关系通过应用程序各函数之间的调用关系展示了系统的结构。②模块控制流图由许多结点和连接结点的边组成的图形其中每个结点代表一条或多条语句边表示节点间的控制流向用于显示函数的内部逻辑结构。★ ★ ★ 2) 错误静态分析静态错误分析主要用于确定在源程序中是否有某类错误或“危险”结构。①类型和单位分析数据类型的错误和单位上的不一致。②引用分析引用异常变量赋值先引用或赋值未引用。③表达式分析表达式错误不正确使用括号数组下标越界等。④接口分析模块的接口参数的一致性。三、动态白盒测试1、逻辑覆盖法1定义逻辑覆盖是以程序内部的逻辑结构为基础来设计测试用例的测试技术通过对程序内部的逻辑结构的遍历来实现程序的覆盖。它属于白盒测试中动态测试技术之一。26种逻辑覆盖方法从覆盖源程序语句的详尽程度分析逻辑覆盖包括以下6种覆盖标准语句覆盖SC判定覆盖DC条件覆盖CC判定-条件覆盖CDC条件组合覆盖MCC路径覆盖。接下来将对这6种逻辑覆盖方法进行一一讲解。1语句覆盖SC①定义语句覆盖(Statement Coverage)的含义就是设计足够的测试用例使得被测程序中每条语句至少执行一次。又称行覆盖、段覆盖、基本块覆盖它是最常见的覆盖方式。②例子展示Question如下java语言程序语句和对应的程序流程图public class Test{ public void Test1(int x,int y,int z){ if(y1 z0){ x(int)(x/y) } if(y2 || x1){ xx1 } } }请使用语句覆盖来为该程序设计测试用例。Answer为了使每条语句都能够至少执行一次我们可以构造以下测试用例输入x4,y2,z0执行路径为sacbed语句覆盖虽然可以测试执行语句是否被执行到但却无法测试程序中存在的逻辑错误。因此语句覆盖是一种弱覆盖。例如如果上述程序中的第一个逻辑判断符号“”误写了“||”使用测试用例同样可以覆盖sacbed路径上的全部执行语句但却无法发现错误。同样如果第二个逻辑判断符号“||”误写了“”使用同样的测试用例也可以执行sacbed路径上的全部执行语句但却无法发现上述逻辑错误。③语句覆盖的目的语句覆盖的目的是测试程序中的代码是否被执行它只测试代码中的执行语句这里的执行语句不包括头文件、注释、空行等。语句覆盖在多分支的程序中只能覆盖某一条路径使得该路径中的每一个语句至少被执行一次但不会考虑各种分支组合情况。2判定覆盖DC①定义判定覆盖(Decision Coverage)又称为分支覆盖其原则是设计足够的测试用例使得程序中每个判定语句的取真和取假分支至少被执行一次。除了双值的判定语句外还有多值判定语句如case语句因此判定覆盖更一般的含义是使得每一个判定获得每一种可能的结果至少一次。②例子展示Question如下java语言程序语句和对应的程序流程图public class Test{ public void Test2(int x,int y,int z){ if(y1 z0){ x(int)(x/y) } if(y2 || x1){ xx1 } } }请使用判定覆盖来为该程序设计测试用例。Answer以上述代码为例构造以下测试用例即可实现判定覆盖标准输入①x1,y3,z0执行路径为sacbd判断的结果分别为TF输入②x3,y1,z1执行路径为sabed判断的结果分别为FT上述两组测试用例不仅满足了判定覆盖而且满足了语句覆盖从这一点可以看出判定覆盖比语句覆盖更强一些。所以只要满足了判定覆盖就一定满足语句覆盖反之则不然。判定覆盖仍然具有和语句覆盖一样无法发现逻辑判断符号“”误写了“||”的逻辑错误。判定覆盖仅仅判断判定语句执行的最终结果而忽略每个条件的取值所以也属于弱覆盖。3条件覆盖CC①定义条件覆盖(Condition Coverage)指的是设计足够的测试用例使判定语句中的每个逻辑条件取真值与取假值至少出现一次。例如对于判定语句if(a1 OR c0)中存在a1、c0两个逻辑条件设计条件覆盖测试用例时要保证a1、c0的“真”、“假”值至少出现一次。②例子展示Question如下java语言程序语句和对应的程序流程图public class Test{ public void Test3(int x,int y,int z){ if(y1 z0){ x(int)(x/y) if(y2 || x1){ xx1 } } }请使用条件覆盖来为该程序设计测试用例。Answer要使程序中每个判断的每个条件都至少取真值、假值一次我们可以构造以下测试用例输入①x1,y2,z0执行路径为sacbed条件的结果分别为TTTF输入②x2,y1,z1执行路径为sabed条件的结果分别为FFFT从条件覆盖的测试用例可知使用2个测试用例就达到了使每个逻辑条件取真值与取假值都至少出现了一次但从测试用例的执行路径来看条件分支覆盖的状态下仍旧不能满足判定覆盖即没有覆盖bd这条路径。相比于语句覆盖与判定覆盖条件覆盖达到了逻辑条件的最大覆盖率但却不能保证判定覆盖。4判定-条件覆盖CDC①定义要求设计足够的测试用例使得判定语句中所有条件的可能取值至少出现一次同时所有判定语句的可能结果也至少出现一次。例如对于判定语句if(a1 AND c1)该判定语句有a1、c1两个条件则在设计测试用例时要保证a1、c1两个条件取“真”、“假”值至少一次同时判定语句if(a1 AND c1)取“真”、“假”也至少出现一次。②例子展示Question如下java语言程序语句和对应的程序流程图public class Test{ public void Test3(int x,int y,int z){ if(y1 z0){ x(int)(x/y) } if(y2 || x1){ xx1 } } }请使用判定条件覆盖来为该程序设计测试用例。Answer为满足判定-条件覆盖原则我们可以构造以下测试用例输入①x4,y2,z0覆盖路径sacbed判断的结果分别为TT条件的结果分别为TTTT输入②x1,y1,z1覆盖路径sabd判断的结果分别为FF条件的结果分别为FFFF判定-条件覆盖满足了判定覆盖准则和条件覆盖准则弥补了二者的不足。但是判定-条件覆盖不一定比条件覆盖的逻辑更强。③判定-条件覆盖的缺点没有考虑条件的组合情况。5条件组合覆盖MCC①定义条件组合(Multiple Condition Coverage)指的是设计足够的测试用例使得每个判定中条件的各种可能组合都至少执行一次。满足了判定覆盖、条件覆盖、判定-条件覆盖准则。②例子展示Question如下java语言程序语句和对应的程序流程图public class Test{ public void Test4(int x,int y,int z){ if(y1 z0){ x(int)(x/y) } if(y2 || x1){ xx1 } } }请使用条件组合覆盖来为该程序设计测试用例。Answer为满足条件组合覆盖原则我们可以构造以下测试用例输入①x4,y2,z0覆盖路径sacbed条件的结果分别为TTTT输入 ②x1,y2,z1覆盖路径sabed条件的结果分别为TFTF输入③x2,y1,z0覆盖路径sabed条件的结果分别为FTFT输入 ④x1,y1,z1覆盖路径sabd条件的结果分别为FFFF由于这4个条件每个条件都有取“真”、“假”两个值因此所有条件结果的组合有242416种。但是当一个程序中判定语句较多时其条件取值的组合数目也较多。需要设计的测试用例也会增加这样反而会使测试效率降低。6路径覆盖①定义路径覆盖指的是设计足够的测试用例使得程序中的每一条可能组合的路径都至少执行一次。②例子展示Question如下java语言程序语句和对应的程序流程图public class Test{ public void Test5(int x,int y,int z){ if(y1 z0){ x(int)(x/y) } if(y2 || x1){ xx1 } } }请使用路径覆盖来为该程序设计测试用例。Answer为满足路径覆盖原则我们可以构造以下测试用例输入①x4,y2,z0覆盖路径sacbed判定的结果分别为TT输入②x1,y2,z1覆盖路径sabed判定的结果分别为FT输入③x1,y3,z0覆盖路径sacbd判定的结果分别为TF输入④x1,y1,z1覆盖路径sabd判定的结果分别为FF2、基本路径测试法1独立路径独立路径是指包括一组以前没有处理的的语句或条件的一条路径。从控制流图来看一条独立路径是至少包含一条在其他独立路径中从未有过的边的路径。2程序控制流图1程序控制流图的定义控制流程图是描述程序控制流的一种图示方式。有向图2控制流图的两种图形符号图中的每一个圆圈称为流图的结点表示一个或多个无分支的语句或源程序语句。流图中的箭头称为边或连接表示控制流线。3程序控制流图的5种基本结构4程序控制流图的描述程序控制流图实际上可以看作是一种简化了的程序流程图。在控制流图中只关注程序的流程不关心各个处理框的细节。因此原来程序流程图中的各个处理框包括语句框、判断框、输入/输出框等都被简化为结点一般用圆圈表示而原来程序流程图中的带有箭头的控制流变成了控制流图中的有向边。5举个栗子下图是典型的程序流程图转换为相对应的流图。对a图所示的程序流程图进行简化得到b图所示的流图。6注意事项在将程序流程图简化成控制流图时应注意如下几点一组顺序结构可以映射为一个单一的结点。在选择多分支结构中分支的汇集处时即使没有执行语句也应该添加一个汇聚结点。边和结点圈定的范围叫做区域当对区域计数时图形外的区域也应记为一个区域开放区域。如果判断中的条件表达式是由多个逻辑运算符ORAND…连接的复合条件表达式则需要改为一系列只有单个条件的嵌套的判断。3软件复杂度软件复杂度是指理解和处理软件的难易程度。程序复杂度是软件度量的重要组成部分。度量方法McCabe度量法环路度量4程序复杂度环路复杂度又称为圈复杂度是一种为程序逻辑复杂度提供定量尺度的软件度量。它可以提供程序基本路径集的独立路径数量这是确保所有语句至少执行一次的过程所必须的最少测试用例数。常用于基本路径测试法。5环路复杂度McCabe复杂性度量方式有如下三种⭐️⭐️⭐️1通过控制流图的区域个数来计算公式V(G)区域数程序的环路复杂性为控制流图的区域数即封闭的区域数1。在下图中可以看到有1和2两个封闭区域因此环路复杂度V(G)2 1 3。个封闭的区域个开放区域2通过控制流图的边数和结点数来计算公式V(G) e - n 2其中e即edge表示图中边的数目n即node表示结点个数。下图中V(G) e - n 2 条边 − 个结点 2 3。因此环路复杂度V(G)。3通过控制流图中的判定结点个数来计算公式V(G) P 1其中P表示判定结点的数目。所谓判定节点数即有多个分支的节点比如下图中的节点2它可以走3或者5这个时候它就需要做判断了。所以2是一个判定节点。同样地下面的 节点3也像节点2一样分析。因此图中V(G)个判定结点1 3所以环路复杂度为。讲到这里我们来给环路复杂性做个小结。事实上程序的环路复杂性给出了程序基本路径集中的独立路径条数这是确保可执行语句至少执行一次所必需的测试用例数目的上界。通过对以上三个例子的了解相信大家对环路复杂度的三种求解方式有了一个新的认识。有了上面一系列内容的铺垫我们来开始讲解基本路径测试法。6基本路径测试法1基本路径测试法是什么路径测试就是从一个程序的入口开始执行所经历的各个语句的完整过程。从广义的角度讲任何有关路径分析的测试都可以被称为路径测试。完成路径测试的理想情况就是做到路径覆盖但对于复杂性较大的程序要做到所有的路径覆盖测试所有可执行路径是不可能的。在不能做到所有路径覆盖的情况下如果某一程序的每一个独立路径都被执行到那么就可以认为程序中的每个语句都已经检验过了即达到了语句覆盖。这种测试方法就是通常所说的基路径测试法。基本路径测试法是在程序控制流图的基础上通过分析控制构造的环路复杂性导出基本可执行路径的集合从而设计测试用例的方法。设计出的测试用例要保证在测试中程序的每个可执行语句至少执行一次。2基本路径测试法的4个步骤基本路径测试法包括以下4个步骤以详细设计或源代码作为基础绘制程序的控制流图。计算得到的控制流图G的环路复杂性VG。确定独立路径的集合。通过程序控制流图导出基本路径集列出程序的独立路径。所谓独立路径是指至少包含一条新边的路径也就是包含一些前面的路径未包含的语句当所有的语句都包含了基路径集就够了。线性无关路径设计测试用例确保基本路径集中每条路径的执行。3例子阐述1依据以下代码用基本路径测试法设计该程序的测试用例。if(a8 b10) //1,2 mm1; //3 if(a10 || c5) //4,5 mm5; //6解答①绘制程序控制流图如下图所示。②计算环路复杂度V(G)43个封闭区域1个开放区域③确定线性无关路径路径11、4、6路径21、4、5、6路径31、2、4、5、6路径41、2、3、4、5、6④设计测试用例编号输入数据预期输出覆盖路径1a2,b3,c4m01、4、62a2,b3,c8m51、4、5、63a10,b6,c8m51、2、4、5、64a10,b15,c8m61、2、3、4、5、64例子阐述2依据以下代码用基本路径测试法设计该程序的测试用例。class Test{ static void permute_args(int panonopt_start, int panonopt_end, int opt_eng, int ncycle){ int cstart, cycle, i, j, nnonopts, nopts, pos; //1 nnonopts panonopt_end - panonopt_start; nopts opt_end - panonopt_end; cyclelen (opt_end - panonopt_start)/ncycle; for(i 0; i ncycle; i){ //2 cstart panonopt_end i; //3 pos cstart; for(j 0; j cyclelen; j){ //4 if(pos panonopt_end){ //5 pos - nnonopts; //6 }else{ pos nopts; //7 } } } } //8 }【问题1】请针对上述java程序给出满足100%DC判定覆盖所需的逻辑条件。【问题2】请画出上述程序的控制流图并计算其控制流图的环路复杂度V(G)。【问题3】请给出问题2种控制流图的线性无关路径。解答【问题1】满足100%判定的逻辑条件为incycle; incycle; jcyclelen; jyclelen; pospanonopt_end; pospanonopt_end;【问题2】控制流图如下图所示V(G)4。【问题3】线性无关路径路径11、2、8路径21、2、3、4、2…路径31、2、3、4、5、6、4…路径41、2、3、4、5、7、4…四、写在最后对于软件测试中的白盒测试来说主要需要了解白盒测试的基本概念静态和动态白盒测试的方法内容较黑盒测试来说逻辑性会更强一些。同时值得注意的是在动态测试中的基本路径测试法中线性无关路径的识别要尤为小心在计算过程中很容易出现多写的问题。因此在此基础上大家可以再多找几道相关的题目进行练习举一反三。最后下方这份完整的软件测试 视频教程已经整理上传完成需要的朋友们可以自行领取【保证100%免费】​​​软件测试面试文档我们学习必然是为了找到高薪的工作下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料并且有字节大佬给出了权威的解答刷完这一套面试资料相信大家都能找到满意的工作。