首页 > 其他 > 详细

功能+自动化测试代码扫描(demo)

时间:2020-07-03 13:36:10      阅读:331      评论:0      收藏:0      [点我收藏+]
  • 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分支。后面可以选择对应的分支了

技术分享图片

 

 

 

 

 

 

好了  到此结束

 

 

 

 

 

 

 

 

 

 

 

 

功能+自动化测试代码扫描(demo)

原文:https://www.cnblogs.com/emars/p/13229671.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!