结合Java代码覆盖率框架jacoco,进行白盒测试

本文介绍了白盒测试的概念,强调了jacoco在代码覆盖率统计中的重要性,讨论了各种测试用例设计方法(如静态代码评审、动态分支/条件/逻辑覆盖),并分析了白盒测试的优缺点,提倡结合黑盒测试以确保全面的测试覆盖。
摘要由CSDN通过智能技术生成

目录

一、什么是白盒测试:

二、为什么要依赖jacoco做代码覆盖率的统计?

三、白盒测试用例常见的几种设计方法:

1、静态方法(不去执行代码):

2、动态方法(执行代码逻辑——测试同学常用):

   (1)分支覆盖法:

   (2)条件覆盖法:

   (3)分支条件覆盖法:

   (4)逻辑(路径)覆盖法:

四、白盒测试的优、缺点:

五、使用jacoco框架的相关命令:

一、什么是白盒测试:

盒子内部的实现,也就是内部的代码逻辑的测试。可以依据代码内部逻辑,进行设计测试用例,对代码内部所有的路径、判断、条件进行测试(主要基于服务端的Controller层、service层、RPC层等进行正常、异常逻辑处理的测试);所以白盒测试是一种基于代码逻辑的测试,主要是根据内部的代码实现,来设计测试用例,得出预期的测试数据。代码逻辑覆盖的越高(覆盖率越高),也就是测试的越全面。

那么如何知道自己所测的逻辑被覆盖到了,有两种方式,第一种梳理代码逻辑,通过查看服务端代码日志的调用链路,结合代码自己人为去梳理;第二种,流水线中集成代码覆盖率统计工具,来统计测试代码的执行情况。

二、为什么要依赖jacoco做代码覆盖率的统计?

jacoco是一个免费的、开源的Java代码覆盖率统计工具,其原理就是通过jacoco提供的代码agent(探针),对所测代码进行插桩,以达到统计代码执行的埋点信息;

测试同学可以通过分析未覆盖到的的代码,反推测试用例设计是否充分,没有覆盖到的代码是否存在问题;没有覆盖到的代码其实是比较危险的,你现在没有覆盖到,上线后不代表用户不会走到这块逻辑;如果看不懂代码也没关系,不具备白盒测试能力,可以通过颜色来进行区分;如下图:


绿色标识:所有的分支均已覆盖;

黄色标识:部分分支被执行;

红色表示:所有的分支均未被覆盖;

三、白盒测试用例常见的几种设计方法:

1、静态方法(不去执行代码):

(1)代码评审———CodeReview

(2)静态代码扫描工具————sonar

2、动态方法(执行代码逻辑——测试同学常用):

(1)分支覆盖法:

设计测试用例,每个分支(判定)的两种情况(True  /  False),都得至少覆盖一次;例如下面这块代码中有2个if判断,判断执行结果有4个;

1 int rs = 0;
2 //前端传过来的值封装在JavaBean中,可以理解为  a >0 && b >0;
3  if (white.getA() > 0 && white.getB() > 0) {    
4      rs = white.getA() + white.getB() + 10;
5     System.out.println("第一条语句,执行完成。。。。。。。");
6 } else {
7      rs = white.getA() + white.getB() - 10;
8     System.out.println("第二条语句,执行完成。。。。。。。");
9       }
10
11 if (white.getC() < 0) {
12      rs = 0;
13     System.out.println("第三条语句,执行完成。。。。。。。");
14        }
15
16    System.out.println("第四条语句,执行完成。。。。。。。");
17  return rs;

测试用例

客户端,预期服务端,预期
a =1,b=2,c= 1

rs :13

执行1,4语句
a=-1,b=0,c=-1rs :0   执行2、3、4语句

方式一:通过日志,查看实际测试结果

测试用例

客户端,实际服务端,实际
a =1,b=2,c= 1
a=-1,b=0,c=-1

方式二:通过代码覆盖率工具统计查看:

分支覆盖的缺点:上述代码虽然是100%的覆盖率,但是如果将  “&&”   改成  “||” ,使用以上的测试用例依然能跟上述的预期结果保持一致,所以分支覆盖是无法发现条件内部的逻辑判断的;

3  if (white.getA() > 0 || white.getB() > 0) {    
(2)条件覆盖法:

设计测试用例,使得每个判断中的,每个条件都至少有一次取的True值,有一次取False值。

上述代码利用条件覆盖法,设计测试用例:

测试用例

客户端,预期服务端,预期
a =12,b=0,c= 10

rs :2

执行2,4语句
a=-12,b=15,c=-10rs :0   执行2、3、4语句

实际测试结果:

测试用例

客户端,预期服务端,预期
a =12,b=0,c= 10
a=-12,b=15,c=-10

方式二:通过代码覆盖率工具统计查看:

条件覆盖的缺点:通过代码覆盖率以及服务端日志发现,语句1那个分支是漏测的。所以说当满足100%条件覆盖的同时,并不能保证所有的分支都会被覆盖到;此时我们依赖jacoco做代码覆盖率统计的作用就体现出来了。

(3)分支条件覆盖法:

设计测试用例,每个分支(判定)的两种情况(True  /  False),都得至少覆盖一次;同时使得每个判断中的,每个条件都至少有一次取的True值,有一次取False值。即同时满足100%的分支覆盖,100%的条件覆盖。基本算是最优的测试方法。

上述代码利用分支、条件覆盖法,设计测试用例:

测试用例

客户端,预期服务端,预期
a =22,b=44,c= 10

rs :76

执行1,4语句
a=-22,b= 0, c=-10rs :0   执行2、3、4语句

实际测试结果:

测试用例

客户端,预期服务端,预期
a =22,b=44,c= 10
a=-22,b= 0, c=-10

(4)逻辑(路径)覆盖法:

设计测试用例,覆盖代码中所有可能组合的路径。目前测试中最常用的一种测试方法。

/* 需求:
   5-10为旺季,头等舱9折,经济舱8.5折;
   11月到来年4月淡季,头等舱7折,经济舱6.5折优惠。
   计算出当前用户的优惠价。
   */
 public double calcute(Compute compute) {
        double price = 0;
        //1、判断月份
        if (compute.getMonth() >= 5 && compute.getMonth() <= 10) {  //旺季
            System.out.println("------语句1------");
            //2、判断仓位类型
            switch (compute.getType()) {
                case "头等舱":
                    price = compute.getPrice() * 0.9;
                    System.out.println(compute.getMonth()+ "月:" + compute.getType()+ "的仓位价格为:"+ price+"元");
                    System.out.println("------语句2------");

                    break;
                case "经济舱":
                    price = compute.getPrice() * 0.85;
                    System.out.println(compute.getMonth()+ "月:" + compute.getType()+ "的仓位价格为:"+ price+"元");
                    System.out.println("------语句3------");
                    break;
            }
        } else {  //淡季
            System.out.println("------语句1.1------");
            switch (compute.getType()) {
                case "头等舱":
                    price = compute.getPrice() * 0.7;
                    System.out.println(compute.getMonth()+ "月:" + compute.getType()+ "的仓位价格为:"+ price+"元");
                    System.out.println("------语句2.2------");
                    break;
                case "经济舱":
                    price = compute.getPrice() * 0.65;
                    System.out.println(compute.getMonth()+ "月:" + compute.getType()+ "的仓位价格为:"+ price+"元");
                    System.out.println("------语句3.3------");
                    break;
            }
        }
        System.out.println("=======语句4=======");
        return price;

    }

需要覆盖的测试路径:

路径1:语句1———》语句2———》语句4;

路径2:语句1———》语句3———》语句4;

路径3:语句1.1———》语句2.2———》语句4;

路径4:语句1.1———》语句3.3———》语句4;

设计测试用例数据:

测试数据

客户端,预期服务端,预期

"price":1000,"month":5,"type":"头等舱"

price:900

执行1,2,4语句
"price":1000,"month":10,"type":"经济舱"price:850执行1、3、4语句
"price":1000,"month":4,"type":"头等舱"price:700执行1.1,2.2,4语句
"price":1000,"month":11,"type":"经济舱"price:650执行1.1,3.3,4语句

方式一:通过日志,查看实际测试结果

测试数据

客户端,实际结果服务端,实际结果

"price":1000,"month":5,"type":"头等舱"

"price":1000,"month":10,"type":"经济舱"
"price":1000,"month":4,"type":"头等舱"
"price":1000,"month":11,"type":"经济舱"

方式二:通过代码覆盖率工具统计查看:

四、白盒测试的优、缺点:

那么它有哪些优点呢:代码覆盖率高;可以清晰的看到那些场景被覆盖,那些未被覆盖,及时补充测试用例。

同时也有缺点:

(1)、难度大,往往业务逻辑复杂的会有很多判断,例如 if....else if... else ;for 循环;while循环;switch判断; try ... catch...等等;

(2)、业务功能可能会覆盖不全,因为我们是基于代码逻辑实现测试,如果说业务场景没有考虑全面的话,就算测的再详细,覆盖率再高,也会漏测,也达不到用户的需求 ;

因此,白盒测试也得和黑盒测试结合起来测试,对于重点的,业务逻辑复杂的,我们的进行白盒测试,保证这些模块所有的路径都被覆盖全。

五、使用jacoco框架的相关命令:

//1、运行服务时使用javaagent设置代理进行插桩
java -javaagent:jacocoagent.jar=includes=*,output=tcpserver,port=6300,address=localhost,append=true -jar springbootdemo-0.0.1-SNAPSHOT.jar


//2、依赖jacococli包dump生成在exec文件,改文件用于存储数据
java -jar jacococli.jar dump --address localhost --port 6300 --destfile ./jacoco-demo.exec


/*3、全量覆盖率统计,通过report命令,生成报告,根据文件生成覆盖率报表,但是得找到源代码,class文件路径、java文件;*/

java -jar jacococli.jar report jacoco-demo.exec --classfiles D:\springbootdemo\target\classes --sourcefiles  D:\springbootdemo\src\main\java --html html-report --xml report.xml --encoding=utf-8
  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值