鉴源实验室 | 软件代码结构化覆盖测试-分支覆盖

news/2024/11/28 2:50:50/

作者 | 李伟 上海控安安全测评部总监

来源 | 鉴源实验室

社群 | 添加微信号“TICPShanghai”加入“上海控安51fusa安全社区”

引言: 上一篇开始我们介绍白盒的代码结构覆盖率测试,已经完成了语句覆盖测试的讲解,本篇我们介绍分支覆盖。

01

关于定义

从测试技术对代码的测试程度上来说,在复杂代码中,分支覆盖比语句覆盖效果要好。很多时候分支覆盖也被叫做判定覆盖。语句覆盖是要求设计的测试用例可以让所有的语句都能够被执行测试。分支覆盖是要求设计用例对代码中所有的逻辑判定分支都被执行测试,也就是每次判定逻辑上真假两种的分支执行情况都覆盖。从定义上我们就可以看出两种方法的测试度量角度是不一样的。计算方法上,语句覆盖的分母是代码总行数,分支覆盖的分母是代码中所有判断的分支总数。

02

分支覆盖测试的举例

我们使用下面一段简单代码来举例说明:

8227.jpg

这段代码总共11行,一个逻辑判断的条件,即x<10为真或假,我们可以看到输入的变量a和b决定了输出值y。对于这段代码的分支覆盖测试设计,我们令a=5或a=15,对应x<10为真或假两种情况。a=5时x<10为真,测试用例执行了代码的第1-6行进入了逻辑真的分支,a=15时x<10为假,代码执行了第1、2和8至11行,执行了逻辑为假的分支。这两条测试用例覆盖全部的两个判定分支,分支覆盖率为100%。

这上面这段代码中,我们针对分支覆盖设计了两条测试用例,达到了覆盖率100%,我们可以发现同样是这两条测试设计,语句覆盖率一样达到了100%,那语句覆盖跟分支覆盖的区别如何体现呢,同样是这段代码我们实际中很多时候是用下面的习惯编写,如:

8228.jpg

这段代码的效果跟前面举例中代码的效果是一样的,对于分支覆盖设计也是一样,因为同样只有一个判定条件,需要分别测试x<10为真或假的两种分支情况,但是语句覆盖设计就不一样了,语句覆盖设计只需要设计一条用例,令a=5即可以覆盖所有的代码语句。这里我们就可以看出分支覆盖的结构化程度高于语句覆盖。

上面的例子相对简单,我们把这段代码稍微变动,来深入探讨一下分支覆盖。示例代码如下:

8229.png

我们可以看到这段代码的逻辑判断了一次,代码同样有两个分支,针对分支覆盖测试我们只需要针对x < 10 && y > 10 == 0 为真或假两种情况,即我们可以令a=15或b=5时代码判断进入条件真的分支,令a=5且b=15代码判断进入条件假的分支。

上面的例子我们也可以看出,分支覆盖测试我们仅在if后面的整体判定语句上取了真和假两种情况,并未深入到该行代码语句中每个判定条件来取真假。

03

使用工具来进行分支覆盖测试

本章节我们继续使用SmartRocket TestGrid这款工具进行代码的分支覆盖测试分析,给大家介绍工具是如何生成测试用例完成测试任务的。

3.1 工具测试举例

针对如下代码:

82210.png

这段代码我们可以看到函数的形参有两个,分别是lua_State *L、init idx,代码逻辑也较为简单,当more为真时执行api_incr_top(L),为假时执行L->top -= 1。more为代码块中定义的局部变量,被赋值为luaH_next(L, hvalue(t), L->top - 1)。

工具自动分析后会生产控制流图如下:

82211.png

控制流图可以直观地看到在本例中两条分支情况,我们可以设计测试用例令more分别为真和假,分别覆盖两条分支,这样就可以完成分支100%覆盖。

我们通过查看项目头文件可以得到函数luaH_next()的形参hvalue(t)已有定义,通过宏替换变为luaH_next (L, ((&((((union GCUnion *)((((t)->value_).gc))))->h))), L->top - 1),可以通过工具来生成用例中的桩函数,下图为工具自动生成的测试用例1:

82212.png

本条用例中桩函数的返回值控制了判断条件的真或假,本条测试用例覆盖的是代码中为真的分支语句。代码中函数的最终返回值也是由more变量决定,我们在用例的输出也可以看到实际返回值跟桩函数的返回值是一样的。

下图为测试用例2:

82213.png

本例中桩函数luaH_next()的返回值设置为0,所以覆盖的是代码中判断结果为假语句分支代码。对于用例中的输入形参,在执行过程中影响了桩函数和执行语句,间接影响本例中的判断条件取值。

我们可以看到工具通过这两条测试用例分别覆盖了两个判断的分支,所以这段代码的测试分支覆盖率就是100%。

04

测试小结

在执行分支覆盖测试时我们有以下建议供大家参考。

1. 通常sil等级不同要求执行的结构覆盖方法会不一样,但是语句覆盖通常会和分支覆盖一起出现在低sil等级的测试要求中。

2. 语句覆盖和分支覆盖的覆盖率统计维度是不一样的,语句覆盖是以代码行数为分母,分支覆盖是以代码中逻辑判断的分支总数为分母。

3. 在合并执行语句覆盖和分支覆盖时测试用例是可以复用的,我们可以在语句覆盖的基础上叠加用例来完成未被测试的分支部分覆盖。


http://www.ppmy.cn/news/1078790.html

相关文章

js对中文进行base64编码和解码操作,解决中文乱码问题

我使用github api的接口获取文件内容&#xff0c;然后使用atob进行解码&#xff0c;但是发现&#xff1a;乱码.......糟心啊 所以就有了我封装的方法&#xff1a; export const encode64 (str) > {// 首先&#xff0c;我们使用 encodeURIComponent 来获得百分比编码的UTF…

vue3 页面显示中文,分页显示中文

vue3 分页默认为英文 &#xff0c;但想要中文显示 那么在App.vue中的代码为三步即可&#xff0c;引入中文&#xff0c;声明中文 &#xff0c;绑定中文&#xff1b; 1. import zhCn from element-plus/es/locale/lang/zh-cn&#xff1b; 2. let locale zhCn; 3. :locale&q…

Oracle常用权限处理

对于Oracle来说&#xff0c;用户等于Schema&#xff0c;创建用户即创建Schema -- 创建用户 create user TCK_TEXT identified by "TCKTCK"; --赋予登陆权限 grant connect to TCK_TEXT; --查看权限列表 select * from user_role_privs ; select * from user_sys_priv…

跳转语句(个人学习笔记黑马学习)

break语句 #include <iostream> using namespace std;int main() {cout << "请选择副本难度" << endl;cout << "1、普通" << endl;cout << "2、中等" << endl;cout << "3、困难" <…

第五课:C++实现加密PDF文档解密

请注意,未经授权的加密PDF文件解密是非法的,本文仅为学术和研究目的提供参考。 打开加密的PDF文件并获取密钥 在C++中,可以使用pdfium库打开加密的PDF文件。使用pdfium库中的FPDF_LoadCustomDocument函数可以打开具有自定义访问权限的加密文件。该函数接受一个IFX_FileRead*…

分布式集群框架——有关zookeeper的面试考点

3.掌握Zookeeper的概念 当涉及到大规模分布式系统的协调和管理时&#xff0c;Zookeeper是一个非常重要的工具。 1. 分布式协调服务&#xff1a;Zookeeper是一个分布式协调服务&#xff0c;它提供了一个高可用和高性能的环境&#xff0c;用于协调和同步分布式系统中的各个节点…

编译期jni类型转换成字符串

背景: 例如android jni 方法的签名, 这个需要每个用户都要知道具体类型,转化成签名, 要想写好签名, 必须很熟悉 类型对应的签名, 尤其java类对象要加个L, 本文将介绍怎么在编译期过程把类型转化成字符, 多个类型在尽性拼接. 定义基础数据结构 template<char ... ch> str…

【C++入门】string类常用方法(万字详解)

目录 1.STL简介1.1什么是STL1.2STL的版本1.3STL的六大组件1.4STL的缺陷 2.string类的使用2.1C语言中的字符串2.2标准库中的string类2.3string类的常用接口说明 &#xff08;只讲解最常用的接口&#xff09;2.3.1string类对象的常见构造2.3.2 string类对象的容量操作2.3.3string…