功能测试+自动化测试代码覆盖率统计

Jacoco 是一个开源的覆盖率工具。Jacoco 可以嵌入到 Ant 、Maven 中,并提供了 EclEmma Eclipse 插件,也可以使用 Java Agent 技术监控 Java 程序。很多第三方的工具提供了对 Jacoco 的集成,如 sonar、Jenkins、IDEA。

Jacoco 包含了多种尺度的覆盖率计数器,包含指令级(Instructions,C0 coverage),分支(Branches,C1 coverage)、圈复杂度(Cyclomatic Complexity)、行(Lines)、方法(Non-abstract Methods)、类(Classes)

这是对jacoco 的功能和使用的简介,我就不需要过多的描述。我的这篇文章就是一个对docker中服务的一个功能测试+自动测试覆盖率统计的demo:

我将从以下几点进行阐述:

  1. docker 底层文件开放变量
  2. 自助式jenkins JOB创建
  3. Pipeline 自助式覆盖率统计

一 docker 底层文件开放变量:

 

这里开放变量的作用是决定  自助式jenkins JOB  是否执行jacoco 覆盖率代码扫描。因为我们是通过jacocoAgent  这种方式来实现代码覆盖率扫描的。并不是所有的服务都需要

进行代码覆盖率扫描,所以我们做成了这种参数化,方便自助决定是否进行覆盖率扫描。

你可能会有疑问为什么不写死呢?答案是:我们的测试环境中的docker底层文件用的是同一套。

开放变量的参数是:-javaagent:/usr/local/jacoco-agent.jar=includes=*,output=tcpserver,append=true,address=0.0.0.0,port=*****

这里的这个参数传递是在 第二个环节自助式jenkins JOB 创建 中设置的一个输入标签。

二 自助式jenkins JOB创建:

前期可爱的运维同事,帮助我们创建了一个通用的自助构建服务的模板:

    1、jobName  <必填>选项,命名格式:环境-服务名

  2、service_name <必填>服务名称,请对应gitlab上项目名称和生成的jar包名称

  3、app_repo <必填>项目仓库地址,必须以git@开头的ssh地址

  4、jvm_opts(开放变量) <可选填>自定义jvm参数,除默认配置jvm参数之外的自定义jvm参数,默认为空  这里由于我们需要运行jacoco-agent,所以输入:-javaagent:/usr/local/jacoco-        agent.jar=includes=*,output=tcpserver,append=false,address=0.0.0.0,port=****

点击build,会自动生成build后job的地址

点击链接,自跳转到job

 点击build with parameters

 

如上图所示  点击build with parameters后  1、2、3会自动填上之前的参数,这里我们只需要选着4、5  部署的分支和部署环境就完成了自助式jenkins JOB创建。下面你就可以进行功能测试和自动化测试了。

接下来的重点是如何拉取代码覆盖率报告:

这里需要注意的是,jacocoAgent 记录了代码执行的轨迹,如果想通过**.exec 获取html报告,我们需要有对应分支的.class 文件才可能实现。这里参照sonar扫描一样的方式获取

class文件。我们通过PipeLine的方式通过编译对应分支的代码获取class文件。

三  Pipeline 自助式覆盖率统计

这里的的工作主要是通过build   获取class文件,通过.exec文件生成覆盖率报告在jenkins上展示出来

那么是如何是实现的呢?

1、也需要运维像第一部一样创建一个公共job  作用仅仅是build操作,而不需要deploy

2、需要在git上创建一个PipeLine公共脚本  PipleLine 开放几个公共标签

 标签内容是:

  • 服务名称:service_name 
  • 务器地址:address
  • 编译后生成的classes文件相对路径:classPattern
  • 剔除无需统计具体的classes文件:exclusionPattern
  • 源码路径:sourcePattern
  • 仓库地址:app_repo

脚本如下:

pipelineJob("$jobName") {
  parameters {
    stringParam("service_name", "${service_name}",'服务名称')
    stringParam('address', "${address}", '服务器地址')
      stringParam("classPattern", "${classPattern}", '编译后生成的classes文件相对路径')
    stringParam('exclusionPattern', "${exclusionPattern}", '剔除无需统计具体的classes文件,多个以英文逗号,隔开。')
    stringParam('sourcePattern', "${sourcePattern}", '源码路径。')
    stringParam('app_repo', "${app_repo}", '仓库地址')
 
    
    gitParameter {
      name('branch_name')
      branch('')
      type('PT_BRANCH')
      defaultValue('master')
      description('')
      branchFilter('origin/(.*)')
      quickFilterEnabled(true)
        tagFilter('*')
      sortMode('ASCENDING_SMART')
      selectedValue('TOP')
      useRepository("$app_repo")
    }
 
 
 
 
    }
 
  definition {
    cpsScm {
    scm {
        git {
          remote {
            url('git@gitlab.***.cn:***/jenkinspipeline.git')
            credentials('*********************')
          }
          branch('*/master')
        }
      }
      scriptPath("Jenkinsfile-Jacoco")
    }
  }
}

jenkinspipeline  (git文件)

pipeline {
  agent {node {label 'k8s-slave'}}
 
  environment {
    def JAVA_HOME="/usr/local/jdk"
    def M2_HOME="/usr/local/maven"
    def MAVEN_OPTS="-Xmx1024m"
 
    def PATH="/opt/kube/bin:/bin:/sbin/:/usr/bin:/usr/sbin/:/usr/local/bin:$PATH"
 
    def dingding_url="https://oapi.dingtalk.com/robot/send?access_token=**************************"
 
    def harbor_server="***************"
 
    def harbor_auth_id="**********************"
 
    def git_auth_id="*********************"
 
    def ansible_repo="git@gitlab.*********************.git"
 
    def app_repo="git@gitlab.*********************.git"
    
  }
 
  options {
//默认是启用并发构建,disableConcurrentBuilds如果开启则为禁用并发构建
//    disableConcurrentBuilds()
    //保持构建的最大个数
    buildDiscarder(logRotator(numToKeepStr: '20'))
    ansiColor('xterm')
    timestamps()
  }
  
  parameters {
    choice(name: 'service_name', choices: '*********************')
    gitParameter(name: 'branch_name', branchFilter: 'origin/(.*)', defaultValue: 'master', type: 'PT_BRANCH', quickFilterEnabled: 'true', description: '选择需要构建的分支', sortMode: 'ASCENDING_SMART')
  }
 
    post{
    success{
        script {
 
            dingTalk accessToken: "${env.dingding_url}", imageUrl: '*********************', jenkinsUrl: "${env.BUILD_URL}",message: "应用${service_name}构建成功!",notifyPeople: '*********************'
 
            wrap([$class: 'BuildUser']) {
                mail to: "${BUILD_USER_EMAIL}",
                from: "*********************",
                subject: "'${JOB_NAME}' 第${BUILD_NUMBER}次,构建结果通知【成功】",
                body: "本次构建由 ${BUILD_USER} 发起,构建【成功】,构建版本 ${params.service_name}:${params.branch_name} .\n具体构建细节,可以前往${env.BUILD_URL}进行查看。"
            }
 
        }
 
      cleanWs()
 
    }
    failure{
        script {
 
            dingTalk accessToken: "${env.dingding_url}", imageUrl: '*********************', jenkinsUrl: "${env.BUILD_URL}",message:"应用${service_name}构建失败!",notifyPeople: '*********************'
 
            wrap([$class: 'BuildUser']) {
                mail to: "${BUILD_USER_EMAIL}",
                from: "*********************",
                subject: "'${JOB_NAME}' 第${BUILD_NUMBER}次,构建结果通知【失败】",
                body: "本次构建由 ${BUILD_USER} 发起,构建【失败】 ,构建版本 ${params.service_name}:${params.branch_name} .\n具体构建细节,可以前往${env.BUILD_URL}进行查看。"
            }
        }
    }
    unstable{
        script { 
            wrap([$class: 'BuildUser']) {
                mail to: "${BUILD_USER_EMAIL}",
                from: "*********************",
                subject: "'${JOB_NAME}' 第${BUILD_NUMBER}次,构建结果通知【失败】",
                body: "本次构建由 ${BUILD_USER} 发起,构建【失败】,构建版本 ${params.service_name}:${params.branch_name} .\n具体构建细节,可以前往${env.BUILD_URL}进行查看。"
            }
        }
    }
  }
 
 
  stages {
    stage("获取代码") {
      parallel{
        stage('配置构建信息') {
          steps {
            script {
              wrap([$class: 'BuildUser']){
                currentBuild.description = "本次构建由<strong><span style='color:#E53333;'> ${BUILD_USER} </span></strong>发起,构建版本 <strong><span style='color:#E53333;'>${params.service_name}:${params.branch_name}</span></strong>"
              }
            }
          }
        }
 
 
        stage("获取应用代码") {
          steps {
            echo "branch_name: ${params.branch_name}"
            sh 'git config --global http.sslVerify false'
            
            wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
              dir ( "${env.WORKSPACE}" ) {
                git (
                  branch: "${params.branch_name}",
                  credentialsId: "${env.git_auth_id}",
                  url: "${app_repo}"
                )
              }
            }
          }
        }
        
      }
    }
 
    stage("jacoco覆盖率统计") {
      steps {
        dir("${env.WORKSPACE}") {
            sh "pwd"
            sh "mvn clean install -Dmaven.test.skip=true org.jacoco:jacoco-maven-plugin:0.8.2:dump -Djacoco.address=\"${params.address}\" -Djacoco.port=********************* -Djacoco.destFile=jacoco_payment.exec -Djacoco.reset=false"
            jacoco(execPattern:'jacoco_payment.exec',classPattern:"${params.classPattern}",sourcePattern:"${params.sourcePattern}",exclusionPattern:"${params.exclusionPattern}")
                                   
        }  
      }
    }
  }
}

上面的PipeLine 配置好了 下面 看看 页面

注:第一次只能选择master分支。后面可以选择对应的分支了

这篇贴子到这里就结束了,最后,希望看这篇帖子的朋友能够有所收获。

感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
 

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/152877.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

csapp attack lab phase4

csapp attack lab phase4 每个gadget由一系列指令字节组成&#xff0c;最后一个字节为0xc3&#xff0c;编码为ret指令。 举个例子: 48 89 c7 是指令 movq %rax, %rdi&#xff0c; 对应的地址是0x400f15 0x3 也就是0x400f18, 是开始的指令位置。 例如&#xff1a; ret编码为0…

线程安全与同步

线程安全问题是什么 多个线程同时操作同一个共享资源的时候可能会出现业务安全问题&#xff0c;称为线程安全问题。 取钱模型演示 需求&#xff1a;小明和小红是一对夫妻&#xff0c;他们有一个共同的账户&#xff0c;余额是10万元。 如果小明和小红同时来取钱&#xff0c;而…

Vue工程化

目录 一、环境准备 npm 二、Vue整站使用 1、Vue项目创建和启动 区别 目录结构 启动 2、Vue开发流程 App.vue 快速入门 3、API风格 案例 细节注意 代码实现 测试 一、环境准备 介绍&#xff1a;create-vue是Vue官方提供的最新的脚手架工具&#xff0c;用于快速生…

5个高质量的自用原型设计工具分享!

什么是原型&#xff1f;原型可以概括为整个产品推出前的框架设计。设计师可以用它来引导每个人参与这个项目。原型显示了每个部分之间的比重和每个部分之间的联系。原型不仅仅是一个表面的东西&#xff0c;它是可以和用户对话的&#xff0c;向用户解释该如何与产品进行交互。例…

一文讲解关于嵌入式系统程序运行的几个问题

问题1&#xff1a;FLASH中的代码是如何得到运行的呢&#xff1f;比如PC指针是在哪里由谁设置的&#xff1f; 以ARM为例&#xff1a; ARM-cortex-M3/4的单片机&#xff08;比如STM32 等&#xff09;&#xff1a;该类单片机的代码在nor flash中&#xff0c;cortex内核可以直接运行…

Python入门教程之基本语法详解,收藏慢慢学~

文章目录 一、Python输出1、repr() 或 str() 转成字符串2、字符串填充空格进行格式化3、!a (使用 **ascii()**), !s (使用 **str()**) 和 !r (使用 **repr()**) 可以用于在格式化某个值之前对其进行转化 二、Python标识符三、Python保留字符&#xff08;关键字&#xff09;四、…

VC6.0 添加CMarkup文件,程序编译不成功

报错信息 Generating Code... Linking...Creating library Release/Iodevcfg.lib and object Release/Iodevcfg.exp ItemConfigDlg.obj : error LNK2001: unresolved external symbol "public: __thiscall CMarkup::~CMarkup(void)" (??1CMarkupQAEXZ) ItemConfigD…

具有mDNS功能的串口服务器

1.概述: 通过mDNS协议可以获得设备的ID、mac、IP、port等信息&#xff0c;方便计算机在同一个局域网内连接到具有该服务的模块。支持产品有串口服务器、串口转以太网模块、RS485串口转网口芯片等。 图 1 mDNS网络结构图 当具有mDNS的服务的设备接入网络的时候&#xff0c;首先…

leetcode链表必刷题——移除链表元素、设计链表、反转链表、两两交换链表中的节点、删除链表的倒数第 N 个结点、相交链表、环形链表、环形链表 II

文章目录 移除链表元素设计链表反转链表两两交换链表中的节点删除链表的倒数第 N 个结点相交链表环形链表环形链表 II 移除链表元素 题目链接 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节…

1分钟精准预测未来10天天气,谷歌开源GraphCast

11月15日&#xff0c;谷歌旗下著名AI研究机构Deepmind在官网宣布&#xff0c;开源天气大模型GraphCast&#xff0c;并公布了论文。 据悉&#xff0c;GraphCast可以在1分钟内&#xff0c;精准预测而来全球10天的天气情况&#xff0c;同时可以提前预警大暴雨、大风雪、洪水、高温…

KeyarchOS的CentOS迁移实践:使用操作系统迁移工具X2Keyarch V2.0

KeyarchOS的CentOS迁移实践&#xff1a;使用操作系统迁移工具X2Keyarch V2.0 作者&#xff1a; 猫头虎博主 文章目录 KeyarchOS的CentOS迁移实践&#xff1a;使用操作系统迁移工具X2Keyarch V2.0&#x1f405;摘要引言1. 迁移前的精心准备1.1 系统环境介绍1.2 深度数据验证1.2.…

语音识别芯片NRK3301在智能茶吧机的应用

传统的饮水机传大多只能提供热水和冷水&#xff0c;而智能茶吧机则是一款集合了热饮水机、煮茶器、泡茶壶等多种功能于一体的多功能生活电器。它不仅具备了传统饮水机的所有功能&#xff0c;还可以根据不同的需求&#xff0c;提供多种水温的饮水方式&#xff1b;还具备了煮茶和…

Cesium+Vue:地形开挖

作者:CSDN @ _乐多_ 本文记录了在Cesium中进行地形开挖的方法和代码。使用Vue框架。 效果如下所示, 文章目录 前言:配置Cesium一、Vue文件二、创建地形开挖函数库三、创建绘制图形库四、创建提示语库前言:配置Cesium 参考《Vue:Vue项目中的Cesium配置备忘录》

【搭建私人图床】使用LightPicture开源搭建图片管理系统并远程访问

文章目录 1.前言2. Lightpicture网站搭建2.1. Lightpicture下载和安装2.2. Lightpicture网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 现在的手机越来越先进&#xff0c;功能也越来越多&#xff0c;而手机…

安装PostgreSql 9.6版本报错

先去官网&#xff1a;Community DL Page 下载了一个“9.6.24*”版本的PostgreSql&#xff0c;然后开始安装。 安装PostgreSql 报错&#xff1a; Cant install PostgreSQL: An error occurred executing the Microsoft VC runtime installer 第一&#xff0c;先&#xff1a;右…

外汇天眼:「外汇回撤」这术语是指什么?

"外汇回撤"是外汇交易中一个常见的专业术语。对于许多投资者&#xff0c;尤其是初学者来说&#xff0c;可能并不十分理解这个术语的实质。下面我们将详细介绍外汇回撤的含义。 外汇回撤通常被称为"外汇百分比回撤"。在外汇市场出现强烈趋势波动时&#xf…

Python自动化测试之request库详解(三)

做过接口测试的都会发现&#xff0c;现在的接口都是HTTPS协议了&#xff0c;今天就写一篇如何通过request发送https请求。 什么是HTTPS HTTPS 的全称是Hyper Text Transfer Protocol over Secure Socket Layer &#xff0c;是以安全为目标的HTTP通道&#xff0c;简单的讲是HTT…

UI游戏设计模板大放送:7种别具匠心的创意!

随着游戏产业的快速发展&#xff0c;UI游戏设计已经成为一个热门的设计行业&#xff0c;但与之前的设计相比&#xff0c;UI游戏设计还是比较特殊的&#xff0c;主要体现在UI游戏设计难度大&#xff0c;需要大量的手绘内容和对游戏玩法的理解上。这些门槛需要大量的时间去学习&a…

ALlegro怎么恢复到初始操作界面?

1.View 2.UI Settings 3.Reset UI To Default

Python winreg将cmd/PowerShell(管理员)添加到右键菜单

效果 1. 脚本 用管理员权限运行&#xff0c;重复执行会起到覆盖效果&#xff08;根据sub_key&#xff09;。 icon自己设置。text可以自定义。sub_key可以改但不推荐&#xff08;避免改成和系统已有项冲突的&#xff09;。command不要改。 from winreg import *registry r&q…
最新文章