基于Super-Jacoco的精准测试实践之路

灵魂拷问

  • 这个版本的影响范围到底有多大?

  • 研发改动了代码,为什么不通知测试?

  • 测试用例真的全面覆盖了吗?

  • 测试同学的测试覆盖情况该怎么评估?

什么是精准测试

概念

借助技术手段、通过辅助算法对软件测试过程进行可视化、分析及优化的过程,使得测试过程更加可视化、智能、可信和精准。

目标

测试质量的评估不在完全依靠个人经验和业务熟练度,而是通过精准的数据来判定。在测试资源有限的条件下,将用例精简到更加有针对性,提高测试效率,减少漏测风险。

核心
  • 研发:研发人员可以看到测试执行用例的代码细节,帮助快速定位和修复缺陷。

  • 测试:测试人员可以通过代码修改范围快速确定测试用例,减少测试的盲目性,提升测试覆盖率。

精准测试实践

  1. 无需对开发代码做任何改造,只需在服务启动命令中添加javaagent即可。

  2. 依托于Super-Jacoco,基于Jacoco、Git二次开发,收集两个版本间增量代码差异。

  3. 用户执行测试用例,用例执行过程中Jacoco会记录代码覆盖情况。

  4. 生成可视化的HTML覆盖率报告,协助用例覆盖情况精准分析。

整体流程图

7a9cfbf6bf527b7d976b66a2ab32acc6.png

详细使用流程

  1. 业务部署

  • 修改env下虚拟机参数

    env:
      - name: OTHER_VM_OPTIONS
        value: '-javaagent:/jacoco-agent.jar=includes=*,output=tcpserver,address=0.0.0.0,port=28048

    super-jacoco服务需要通过agent启动的服务中拉取exec文件

    address指定为0.0.0.0即可,但是port必须为对外暴漏的端口

  • 添加port

    ports:
      - hostPort: 28048
        containerPort: 28048
        protocol: TCP
  • /home/xxx/org.jacoco.agent-0.8.5runtime.jar:agent Jar包存放路径

  • address: 部署服务器的机器IP

  • port: 部署服务器的空闲port,用于精准测试服务来拉取exec文件

  • 注:如果服务启动时已经有Javaagent参数的,可以再配置一个Javaagent参数,但是Jacoco的agent必须在第一位,如下:

    java -javaagent:jacooc.jar -javaagent:agent2.jar -jar service.jar
  1. 物理机部署业务方服务

    在启动业务方服务时,添加javaagent启动参数

    java -javaagent:/home/xxx/org.jacoco.agent-0.8.5runtime.jar=includes=*,output=tcpserver,address={address},port={port} -jar service.jar
  2. K8S部署业务方服务

    在基础镜像中已经包含了agent的Jar包,业务方可以直接使用。

    修改deploy相关的yaml文件
    修改Service相关yaml
    ports:
      - name: jacoco--serve
        protocol: TCP
        port: 28048
        targetPort: 28048

启动覆盖率收集

在用例执行之前,先启动覆盖率收集,获取两个Git Commit点之间的代码差量报告

Host为Super Jacoco服务启动的ip和port

Host: http://ip:port
Path: /cov/triggerEnvCov
Method: POST application/json
Body: 
{
  "uuid": "{随机ID}",
  "type": 1,
  "gitUrl": "ssh://gitUrl/{your project name}",
  "subModule": "",
  "baseVersion": "commit id",
  "nowVersion": "commit id",
  "address": "{address}",
  "port": "{port}"
}
Response:
{
  "code": 200,
  "msg": "success",
  "data": null
}

参数说明:

可以把接口配置到PostMan中,调用启动覆盖率收集,之后即可执行测试用例

  • uuid:随机值,全局唯一;可手动输入,getEnvCoverResult接口需要使用

  • gitUrl: 项目仓库地址

  • baseVersion: 基准的Git CommitID

  • nowVersion:新版本的Git CommitID

  • address:步骤1中的address

  • port:步骤1中的port

获取覆盖率报告

在测试用例执行后,通过接口/cov/getEnvCoverResult获取覆盖率报告

Host: http://ip:port
Path: /cov/getEnvCoverResult
Method: GET
Query:
 uuid: {uuid}
Response:
{
  "code": 200,
  "msg": "success",
  "data": {
    "coverStatus": 1,
    "reportUrl": "http://ip:port/uuid/index.html",
    "lineCoverage": 60.3,
    "branchCoverage": 50.62,
    "errMsg": "",
    "logFile": "http://ip:port/logs/uuid.log"
  }
}

参数说明:

  • uuid:步骤2中的uuid

  • reportUrl:HTML报告访问地址

访问reportUrl中的地址即可获取覆盖率报告,报告解读:

eb81cce983c337b3ffc6b2e2ea6a6f09.png

上图为某项目的报告截图示例,对报告理解作简单介绍:

  • 绿色:用例执行覆盖到了该代码

  • 黄色:用例执行部分覆盖了该代码的逻辑

  • 红色:该代码逻辑未被覆盖到

  1. 代码标记颜色说明:

  2. 指标含义解释:

    335f4b58dd6a661df9a91bd11fd122ca.png

精准测试使用场景

1. 提测阶段

版本提测后,通过触发【启动覆盖率收集】步骤2中的操作,通过【步骤3】获取覆盖率报告,可以获得本次迭代版本相比上个版本的代码变更范围,为测试同学制定测试方案和测试范围提供参考。同时可以评估研发的自测程度。

2. 测试阶段

测试完成后,通过获取【获取覆盖率报告】步骤3来查看测试覆盖情况,测试同学可以根据代码染色结果来分析本次测试的完成度。同时也可以驱动测试同学加强代码阅读和分析,提升测试深度。

3. 回归阶段

通过PostMan测试集合执行回归用例,除了可以查看测试集合的用例执行结果外,还可以通过覆盖率报告进行分析。

常见问题

  1. Super-Jacoco的git地址是否支持ssh?

    支持,application.properties中的gitlab.usernamegitlab.password配置为空值时使用默认的SSH值。你也可以修改super-jacoco中com.xiaoju.basetech.util.GitHandler的源码来指定SSH配置,示例代码如下:

    private String private_key = "/Users/wang/.ssh/y";
    SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
                @Override
                protected void configure(OpenSshConfig.Host host, Session session) {
                    session.setConfig("StrictHostKeyChecking", "no");
                }
    
                @Override
                protected JSch createDefaultJSch(FS fs) throws JSchException {
                    JSch sch = super.createDefaultJSch(fs);
                    sch.addIdentity(private_key); //添加私钥文件
                    return sch;
                }
            };
    
            Git git = Git.cloneRepository()
                    .setURI(gitUrl)
                    .setTransportConfigCallback(transport -> {
                        SshTransport sshTransport = (SshTransport) transport;
                        sshTransport.setSshSessionFactory(sshSessionFactory);
                    })
                    .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password))
                    .setDirectory(new File(codePath))
                    .setBranch(commitId)
                    .call();
            // 切换到指定commitId
            checkoutBranch(git, commitId);
            return git;
  2. 代码安全问题

    super-jacoco是根据源码来做增量代码差异化分析的,如果使用统一账户拉取代码,那这个账号可能就拥有了所有代码的权限,可以分配只读权限。

  3. K8S中可以使用吗?

    上面的步骤中有K8S的使用方式,主要涉及两个问题,1. agent放在哪里?2. pod重启之后可能IP会变掉?

    1. 可以把agent放入到基础镜像或者打包到项目中。2. 把address配置成0.0.0.0之后,请求参数中的address写成K8S集群的访问Ip即可。

  4. 测试人员无法获取到代码Commit ID?

    可能很多公司的测试其实是没有代码仓库权限的,只是对迭代的版本有直观的认知。这个就需要依赖公司内部的协调处理了。

  5. 覆盖率需要达到100%吗?

    代码覆盖率其实很难达到100%,代码中可能会有一些catch的异常或者lombok生成的代码用例很难覆盖到。而且覆盖率也很难说达到一个稳定的值来作为公司内部测试完成的度量。

结语

借助于super-jacoco,我们可以获取用例执行的覆盖率情况,生成覆盖率报告来协助我们分析用例是否完善。但这才是精准测试迈出的第一步,这个覆盖率报告如何解读,如何作用于研发流程还需要不断实践来总结经验。

未来,还要继续探索如何根据覆盖率来推导代码变动影响的接口范围、分析冗余用例提升回归效率、根据代码变动自定推荐用例等等。

欢迎有兴趣的朋友一起关注交流

3e4c42096d0699da943da3b23cddaeef.png

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值