软件测试的基本理论-白盒测试-2
- 一.白盒测试方法
-
- 1.逻辑覆盖法
-
- 语句覆盖
- 判定覆盖
- 条件覆盖
- 判定-条件覆盖
- 条件组合覆盖
- 二.程序插桩法
-
- 目标代码插桩
- 源代码插桩
- 程序插桩法demo
- 程序插桩法缺点
- HeisenGugs
- 白盒与黑盒比较
)
一.白盒测试方法
通常有语句覆盖、判定覆盖、条件覆盖、判定-条件覆盖、条件组合
语句覆盖 - 设计一套测试 让被测对象中所有语句得到测试覆盖
判定覆盖 - 设计一套测试 让被测对象中所有判定得到测试覆盖
条件覆盖 - 设计一套测试 让被测对象中所有条件得到测试覆盖
路径覆盖 - 设计一套测试 让被测对象中所有路径得到测试覆盖
1.逻辑覆盖法
语句覆盖
又称:行覆盖、段覆盖、基本覆盖
度量被测代码中每个可执行语句是否被执行到了。这里说的是“可执行语句”,因此就不会包括像C++的头文件声明,代码注释,空行,等等
语句覆盖率的公式 :
语句覆盖率=可执行的语句总数/被评价到的语句数量 x 100%
例如:
if x > 0 and y <0:
z = z-(x-y)
if x> 2 or z>0 :
z= z+(x+y)
test case :x= 3 y =-1 z= 2
此用例可一次执行以上场景,对于多分支语句,仅仅执行一次并不能进行全面覆盖,因此,语句覆盖为弱覆盖方法;
语句覆盖可以判断语句是否被执行,但无法判断语句的逻辑错误,所以语句覆盖不能满足白盒测试的所有逻辑语句的基本需求i;
判定覆盖
即分支覆盖;设计足够多的用例,测试过程保证每个判定至少有一次为真值,有一次为假值,
判定覆盖作用:真假分支被执行;
判定覆盖虽然保证每个判定至少有一次执行,但却没有考虑到程序内部的取值情况,因此,判定覆盖也属于弱覆盖;
条件覆盖
指设计足够多的测试用例,使判定条件取真值与取假值至少出现一次,
如图1中例子所示:图中共有两个判定表达式,每个判定表达式中有两个条件,为了做到条件覆盖,应选取测试数据使得在a点有下述各种结果出现。
A>1,A<=1,B=0,B!=0
在b点有下述各种结果出现:
A=2,A!=2,X>1,X<=1
只需要用下面两组测试数据就可以达到标准:
A=2,B=0,X=4;满足A>1,B=0,A=2和X>1的条件,执行路径ace
A=1,B=1,x=1满足A<=1,B!=0,A!=2和X<=1的条件,执行路径abd
判定-条件覆盖
判定条件覆盖是设计足够的测试用例,得使判断中每个条件的所有可能取值至少执行一次,同时每个判断本身所有可能结果也至少执行一次。缺点是忽略了条件的组合情况。
条件组合覆盖
选择足够的测试用例,使得每个判定中条件的各种可能组合都至少出现一次。显然,满足“条件组合覆盖”的测试用例是一定满足“判定覆盖”、“条件覆盖”和“判定/条件覆盖”的。
二.程序插桩法
程序插桩,最早是由J.C. Huang 教授提出的,它是在保证被测程序原有逻辑完整性的基础上在程序中插入一些探针(又称为“探测仪”)
本质上: 就是进行信息采集的代码段,可以是赋值语句或采集覆盖信息的函数调用
过程:通过探针的执行并抛出程序运行的特征数据,通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,从而实现测试目的的方法。
根据探针插入的时间可以分:目标代码插桩、源代码插桩
目标代码插桩
目标代码插桩:(动态程序分析方法)
指向目标代码(二进制)插入测试代码获取程序运行信息的测试方法,插桩之前,测试人员需要对目标代码逻辑结构进行分析,从而确定需要插桩的位置;
优点:
1)对源文件进行完整的词法分析和语法分析的基础上进行的,这就保证对源文件的插桩能够达到很高的准确度和针对性。
2)对内存监控、指令跟踪、错误检测有者重要意义;
3)测试过程中不需要代码重新编译或链接程序,并且目标代码格式与编程语言无关,主要和操作系统有关
缺点:
1)源代码插桩需要接触到源代码,使得工作量较大
2)随着编码语言和版本的不同需要做一定的修改
原理:
程序运行平台和底层操作系统之间建立中间层,通过中间层检测执行程序、修改指令、开发人员软件分析工程师对运行的程序进行观察,判断程序是否受到攻击和出现异常行为。
执行模式
分为两种情况:
一种:对未运行的目标代码插桩,从头到尾插入测试代码,然后执行程序,实现完整系统或仿真时进行的代码覆盖测试;
另一种:向正在运行的程序插入测试代码,用来检测程序在特定时间的运行状态信息;
1)即时模式:
原始的二进制文件和可执行文件没有被修改或执行,将修改的二进制代码生成文件副本存储在新的内存区域中,在测试时候只执行修改的部分的目标代码;
2)解释模式:
在解释模式中目标代码被视为数据,测试人员插入的测试代码作为目标代码指令的解释语言;每当执行一条目标代码时;程序就会在目标代码中查找并执行相应的替代指令,测试通过替代的指令的执行i洗脑洗就可以获取程序的运行信息;
3)探测模式:
使用新指令覆盖旧指令进行测试,这中模式在某些体系结构中比较好用(x86)
目标代码插桩工具
1)DynamoRIO
DynamoRIO框架在操作系统和应用程序之间,构成一个中间层。在该中间层中DynamoRIO将CPU的寄存器做一份完整的镜像,并以此为被测程序构造出一份虚拟的上下文。在DynamoRIO框架下运行着的程序都会使用这份模拟出来的运行时上下文,同时通过DynamoRIO中的上下文切换模块代码即被投入运行之前在真实的宿主机上恢复出原本被虚拟的上下文
组成:DynamoRIO的内核由三个模块组成:调度器(Dispatch)、基本块构建器(Basic block builder)和代码缓存器(Code cache)。其中基本块构建器负责从被测程序中切分出基本块并完成插桩,代码缓存器负责缓存并管理已经插桩完毕的基本块,最后由调度器来截获被测程序的指令,完成内存事件的分发并协调各个模块之间的工作。
参考资料:
https://blog.csdn.net/AlexYoung28/article/details/100025025
2)pin
pin提供了指令、基本块和系统调用等多个层次插桩分析,其中,RTN是函数级的插桩机制,能够自动识别API函数;Trace是轨迹层次的插桩机制,能够自动识别单一入口、多出口的指令轨迹块
Pin是由英特尔公司开发的动态二进制插桩框架,它允许我们为Windows,Linux和OSX构建称为Pintools的程序分析工具。我们可以使用这些工具来监控、修改和记录程序运行时的行为
pin 工具下载:
https://software.intel.com/content/www/us/en/develop/articles/pin-a-dynamic-binary-instrumentation-tool.html
https://software.intel.com/content/www/us/en/develop/articles/pin-a-binary-instrumentation-tool-downloads.html
源代码插桩
源代码插桩是在对源文件进行完整的词法分析和语法分析的基础上进行的,这就保证对源文件的插桩能够达到很高的准确度和针对性。但是源代码插桩需要接触到源代码,使得工作量较大,而且随着编码语言和版本的不同需要做一定的修改
源代码插桩模型:
1)由图可看出源代码插桩时在执行源代码之前完成的,因此源代码插桩会在程序运行中产生探针代码开销,先对于目标代码插桩,此方法实现简单,但源码插桩是源代码级别的测试技术。
程序插桩法demo
程序插桩法缺点
1)有效提高了代码的执行效率,但会带来代码膨胀、执行效率下降和HeisenGugs,一般代码膨胀率在20%-40%。甚至达到100%导致测试失败;
补充:测试理论
性能测试
补充:
HeisenGugs
一种软件缺陷,重现率很低,或者消失或出现了其他的bugs;
白盒与黑盒比较
1)黑盒并不考虑内部结构,关注软件外部,即黑盒可以发现以下缺陷:
外部逻辑功能缺陷,如:界面显示错误
兼容性错误,如系统版本支持、运行环境等
性能问题,如运行速度、响应时间等
2)白盒设计用例尽可能覆盖内部逻辑
源程序含有多个分支,程序设计用例时尽可能覆盖所有分支。
内存泄漏检查迅速,黑盒测试只能在程序长时间运行中发现内存泄漏问题,
测试阶段的不同
测试名称 | 测试对象 | 测试方法 |
---|---|---|
单元测试 | 模块功能-函数、类 | 白盒测试 |
集成测试 | 接口测试-数据传递 | 黑盒、白盒测试 |
系统测试 | 系统测试-软、硬件 | 黑盒测试 |
验收测试 | 系统测试-软、硬、用户体验测试 | 黑盒测试 |