下面我们来看一下白盒测试,白盒测试又称为结构测试,或者是逻辑 驱动测试。
一说白盒,对吧?晶莹剔透,你能看到内部的所有的这样的
一个逻辑,对吧?所以它不是一个黑匣子,只看到一个口,根本不知道内部到底是什么。
那么这个里面,它是知道这个产品的内部工作的过程,那么
通过测试来检测产品的内部的动作是否按照规格说明书的规定来正常地进行。
所以它要按照程序内部的结构
测试程序,来检查程序中每条通路是否按照预定的这个要求来正确地工作。
进而提供它的这样的一个功能,就是白盒测试实际上就是依据的什么?
程序的逻辑处理结构,对吧?就是说,依据程序的处理结构,我看你是不是按照这样的结构一- 步步地去执行。
是不是按照这样的一个执行的结果能够满足用户的这样的一个要求。
所以白盒测试法呢又有这个逻辑覆盖啊、 基本的路径测试等,主要是用于这种软件的这样的一个验证。
我们来看一下白盒测试技术依据的程序的逻辑结构,那么
我们在讲了软件测试的过程的时候,特别强调了说
被测对象,这个软件是非常复杂的,我们对它测试的时候一定要进一步把它
抽象,对吧?形成一个简化的被测对象模型, 再去测试这里面的关键要素。
所以就涉及到白盒测试里面建立被测对象模型
的时候,我们采用一个图形工具,叫控制流程图,那么一种表示程序控制结构的
图形工具,它的基本的元素的节点、 判定和过程块。
过程块呢是既不由判定,也不由节点分开的一组 这个程序的这个语句,比如我们这里面说的
1,3,6,5, 都是这个过程块,包括这个 7 都是过程块。
那么判定呢是一个程序点,大家看,也就是说这个 2 这个地方,
此处控制流可以进行分叉,对吧?这个控制流分成了两个控制流。
那节点呢 是一个程序点,也就是说控制流在这里面结合,对吧?所以在这个里面大家看,两个控制-
流结合。
所以这个是一个这个抽象 被测的对象的这样的一个建模工具。
那我们来举一个简单的例子啊,这是一个程序流程图,大家看非常简单的一个程序流程图,对- 吧?那么
也就是说,这个 a,这是路径啊,b 完了是 c, d,
e 这都是路径,这中间 有两个判定,对吧?那判定实际上是由两个条件来组成的,这个相当于呢是有两个语句,
那我们对这个进一步地给它抽象,形成的
控制流程图就可以是变成这样,这就变成了一个判定,对吧?
也就是说,这个判定的过程中相当于形成两个分支,那么中间呢相当于这里是一个过程块, 这呢相当于是形成的节点
1,这又是一个判定,这过程块又形成了节点 2。
所以,这是一个被测对象相当于就能够通过这样一个图,简化地就描述出来了。
那么各种的测试方法,我们来看一下,因为我们讲了说如果
一个程序中所有的路径我都能让它覆盖到,必然它出现的各种错误我都能发现。
这是一个非常好的这样的一个想法,那也就是说这就是路径测试的
这个一个思想,执行所有可能的穿过程序的控制流图路径。
那一般说来,就是说这一测试严格地限制所有可能的入口和出口路径,对吧? 那在这个过程中,如果我们能达到了
100% 的路径覆盖率, 那么这个程序实际上它所有的错误都能够被检测出来。
所以它的这样的一个策略是最强的,但是大家看,能可以行吗?
能达到吗?不可实现的,对吧?可望不可及。
所以我们退而求其次吧,整个就说,我们怎么能够
相当于在这个简单的这样的一个程序中尽量用这个 路径测试。
那么如果对于复杂的程序而言,路径太多了,我没有办法
去把所有的路径都覆盖到,我再可以采用其他的这样的一个覆盖准则,我们首先来看一下
对于这个简单的程序有几条路径?有这个四条路径,对吧? L1,L2,L3,L4。
那么在这个过程中, 我们要实现所有的路径覆盖,也就是需要这四条路径,相当于
都能够被测试用例去执行覆盖。
那我们就编写了这个四个测试用例,大家看这个测试用例能覆盖了这四条路径
那么测试用例的设计的写法,这里面输入
还有输出,所以大家看,这就对于给定的这个输入形成的输出是这样的。
所以一定记住整个的测试用例,整个一定是 配对的,就是说,没有说光输入,没输出,这不是测试用例。
所以测试用例是对应的是一组对于一组给定的输入, 我形成的一组输出。
所以, 用了这样四组测试用例,我就能实现对刚才的那样的一个程序的完全的路径覆盖。
那我们也讲了说这对于简单的程序而言, 我能够做到,但对于复杂的程序,我们没有办法做到 100% 的路径覆盖。
那么我们就看,我们能不能通过其他的覆盖去测试出尽可能多的错误呢? 那人们就提出了语句覆盖,
也就是说,至少执行程序中的所有语句一次, 遵循这一规则我们就说,达到了 100% 的语句覆盖率。
那么 100% 的语句覆盖率简称为 C1。
那么在这个例子里面,我们只要设计一种 能通过路径覆盖 ace 的测试用例就覆盖了所有的语句。
大家看,也就是说我们的这个例子里面,a,c,e 对吧? 只要执行了整个覆盖这一条路径,我们就能把所有的语句
都给它覆盖了,对吧?所以就达到了 100% 的这样的一个语句的这样的一个覆盖。
那么语句覆盖大家可以看到,就是说
它还是比较弱的这样的一个逻辑覆盖准则,为什么这么来说呢?
因为就程序而言,如果两个判定的逻辑
运算写错了,第一个判定的逻辑运算符比如说"与"写成了"或",
第二个判定的这个逻辑运算符呢"或"写成了"与",那么利用上面的这样的一个测试用例,
就是仍然可以相当于覆盖这个所有的语句。
根本发现不了判断中的,也就是判定中 出现的这的一个逻辑错误,所以大家就可以看到语句
覆盖,尽管我把所有的语句都覆盖,但是对于判定中的错误,我没有办法去 排除,所以进而呢人们又进一步地去
提出了分支覆盖,也就是说至少执行程序中的每一分支一次,
如果遵循这一规则,我们就说达到了 100% 的分支覆盖率。
这个用 C2 来表示啊,100% 的分支覆盖率。
那这个分支覆盖 它是一种比语句覆盖稍微强一点的逻辑覆盖准则,也就是说,
判定里面可能有几个条件构成的时候, 它又出现问题了,虽然说我把这个判定"与""或""非"
所有的这个判定相当于也就说啊,因为都是一组条件的这样的一个 符合构成嘛。
所以在这个过程中出现的问题就是 用判定,整个的符合之后的"与""或""非"相当于我都能走了,但是
如果这里面的条件本身出现了问题,那我没有办法去给它
这个找出来,所以这个里面我们就希望的是 进一步地提出相应的这样的一个逻辑覆盖准则,解决
分支覆盖不能保证查出判定条件中存在的错误。
那我们先来看一下。
就是说利用刚才的这样的一个例子, 我们如果选择了这个路径
L1,L2,给出相应的 这样的一个分支覆盖的测试用例,实际上就能够去覆盖 整个的这样的一个分支。
那么大家看,如果选择了这个 路径 L3 和 L4 呢,得到另一组那个可用的这样的一个测试用例。
所以这个里面,通过这两组测试用例, 我们就能够把所有的分支的这个
非和这个支全都能够给走到啊。
那我们知道说,分支覆盖率对每一个条件 的这个错误我没有办法去给它排除,进而呢人们又说了
那我们就来提另外的测试的这个覆盖准则, 于是条件组合这种测试技术被提出,就是说
设计足够的测试用例,使每个判定中的所有可能 的条件取值至少执行一次。
如果遵循这一个规定呢,相当于就 实现了条件组合的这种覆盖。
那这个里面大家可以看, 只要满足了条件组合的覆盖,一定满足什么?分支覆盖,所以这个过程
这个是人们看到比较好的这样的一个结果。
但是条件组合覆盖不是在分支覆盖之后马上就提出的覆盖技术,
人们在条件组合覆盖技术的这样的一个发展的过程中或者是推出的过程中,人们最开始想到的说
那分支中的每个条件出现的错误,我不能 排除,那我就对每个条件可能出现的所有的情况
都去给它覆盖一下,是不是就可以做到了呢? 当时就出现了一个中间的叫条件覆盖的这样的一种中间的技术,也就说
考虑分支中各个条件的所有可能结果至少出现一次 那这个过程中,大家看,这个有四个条件,比如说
A 大于 1 B 等于 0,A 等于 2,和 X 大于 1,我们反过来再看一下
这里面整个因为有,有两个判定,啊,所以相当于条件就是 A 大于
1 对吧? B 等于 0,还有 A 等于 2,和 X 大于 1,这四种条件,所以这四种条件
怎么来想的呢?也就是说对这四种条件 对吧?A
大于 1,我取值要 True 把它相当于覆盖了,同时对 false 也覆盖了啊。
那么 B 等于 0 取值 真值的时候为 true 2 啊,取假值为 false 2
那么条件 A 等于 2 呢,取真值为 true 3 啊,假值为 false
3,所以等等相当于 那么这四种条件通过相当于这样的一个这个列举,大家就看了,如果我在测试
用例的设计的时候,考虑把这个四个条件,所有的八种的取值都给覆盖了
是不是我的这个相当于所有的这个判定里 的条件出现的问题我都能解决呢?我们来看一下
我们可以通过设计测试用例实现条件覆盖,对吧?大家可以看
那么我通过这两组测试用例,对于给定的输入,啊,形成给定的输出,那么通过了 这个路径只有一条,对吧 L3。
那么条件取值我这四种 取值也都给它覆盖了啊,就是这个四种条件的八种取值
那么覆盖的分支大家可以看,只有什么? b e 啊。
所以这过程大家可以看到,也就是说 虽然说各种条件取的真值和假值我都给它覆盖了
但是没有实现百分之百的分支覆盖,因为这里面的一些分支
没有这个,取值情况没有被覆盖到 所以人们进一步的又提出了条件组合符合覆盖。
也就说对于每一组,每一个判定 它构成的这个条件组合,我要把它的
真和假都能够被覆盖到,所以大家看,通过这样的一个方式
我们对于第一个判定有四种的条件组合,对于第二个判定,又有四种条件组合
那么通过这样的八种条件组合覆盖到的话 我们采用这四组的,啊,测试用例,就能实现
整个的八种的条件组合覆盖 那么这个里面大家可以看,通过这一点,我们来看
它通过了路径 L1 L2 L3 一共四条路径,但它通过了三条对吧?
那么条件呢这八种组合,我已经都覆盖了 同时对于分支也覆盖,也都全部的
cover 了,所以在这个里面我们可以看到
条件组合覆盖是比分支覆盖强一些 但是,还没有实现路径覆盖的一种中间的
测试覆盖技术,那么在这个过程中,啊,软件的这个开发人员经常也
在这个条件组合覆盖和路径覆盖中间希望一直找到一个更进一步的对吧
能够走向百分之百路径覆盖的一个中间技术,所以在不断地进行探索。
那经典的覆盖技术大家形成共识的就是这么几种 大家看这几种的,谁是最弱的?语句覆盖对吧?
其次是分支覆盖,那么条件组合覆盖呢? 虽然说实现了分支覆盖的这样的一个,一个特点
但是呢,对于路径,有些路径我还没有办法给它 cover 到 那么i triple E
给出来了一个 最低的这个强度测试的这个要求,就是要实现 C1
加 C2,也就说百分之百的语句覆盖加百分之百的分支覆盖,这是要求
我们在测试的过程中至少要达到的一个要求
那么前面介绍的是对于普通的这样的一个程序而言,对吧?就说是 我们怎么去进行应用测试用例。
但同时有的时候 我们的程序里面可能还会出现一些循环的路径对吧? 那么这个循环的路径里面,啊,有可能会单循环
啊,单循环大家看整个就是说,我整个单个的循环对吧?对于给定的这样的一个变量
对吧?最小和最大之间相当于,我形成这个循环条件,形成了这样的一组循环
那么这种循环相当于可以按照我们书上介绍的,对吧?比如说可以看这个最小值是不是 0
还是说,非 0 的这样的一个正整数啊,那么以及
最大值那么也就是要取整个循环条件这个边界这个地方 如果最小值是
0 的话,我们要来取这个负 1,0,正 1 这样的一个循环条件的这样的 一个循环,啊。
以及中间的这个值和最大的循环变量,最大循环变量减 1
最大循环变量以及最大循环变量值的一个加 1,整个这样 来构成这个循环的这样的一个测试。
这是非常简单,我们大家可以看书 那么还有的就是这个形成了一个嵌套循环
嵌套循环大家可以看可能是一层一层的对吧?就有一个从内到外的这样的一个循环变量的这样-
的一个控制 所以我们的建议,啊,就说也是从最内层的这个循环开始考虑,那么
从最内层的循环来考虑的话,实际上它又变成了一个什么?
单循环的这样的一个特点对吧?去来考虑那个循环的这样的一个边界值,来去设定 这个相应的测试用例。
那么在这个最内层的循环,以及中间的
典型的循环,和最外层的循环逐步往,往外这样的一步步的测试,来形成循环这个
嵌套循环的这样的一个测试变量,啊,整个的这样的一个测试,所以这个我觉得大家看一下书- ,就很容易就理解了
那么我们在测试的过程中,大家都知道说 我们没有办法是把所有的路径都给它
cover,都给它覆盖 实际上我们在测试中,是要来选择的什么?关键路径
也就对于这个程序而言,我们认为是这些路径是我们必须要考虑的 那么也就说主要的功能的路径,啊,那也就说我们的
程序的执行中,啊,很多的这样的一些功能点,它是体现了一个系统的 逻辑的这样的功能处理的,这样的一些路径。
那么还有没有功能的路径 我可能只是一些相当于中间的这样的一个打酱油的啊,整个,我也得相当于去看一下
那么还有最短的路径,所以通过这样一些路径的这样的一个选择
我们去设置相应的这样的一个测试用例来实现 这个软件的这个测试,啊。
所以这个是对于程序的出现循环 以及路径选择而言,我们要有这样的一个意识