• 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

脚本如下:

  1. pipelineJob("$jobName") {
  2. parameters {
  3. stringParam("service_name", "${service_name}",'服务名称')
  4. stringParam('address', "${address}", '服务器地址')
  5. stringParam("classPattern", "${classPattern}", '编译后生成的classes文件相对路径')
  6. stringParam('exclusionPattern', "${exclusionPattern}", '剔除无需统计具体的classes文件,多个以英文逗号,隔开。')
  7. stringParam('sourcePattern', "${sourcePattern}", '源码路径。')
  8. stringParam('app_repo', "${app_repo}", '仓库地址')
  9.  
  10. gitParameter {
  11. name('branch_name')
  12. branch('')
  13. type('PT_BRANCH')
  14. defaultValue('master')
  15. description('')
  16. branchFilter('origin/(.*)')
  17. quickFilterEnabled(true)
  18. tagFilter('*')
  19. sortMode('ASCENDING_SMART')
  20. selectedValue('TOP')
  21. useRepository("$app_repo")
  22. }
  23.  
  24. }
  25.  
  26. definition {
  27. cpsScm {
  28. scm {
  29. git {
  30. remote {
  31. url('git@gitlab.***.cn:***/jenkinspipeline.git')
  32. credentials('*********************')
  33. }
  34. branch('*/master')
  35. }
  36. }
  37. scriptPath("Jenkinsfile-Jacoco")
  38. }
  39. }
  40. }

jenkinspipeline  (git文件)

  1. pipeline {
  2. agent {node {label 'k8s-slave'}}
  3.  
  4. environment {
  5. def JAVA_HOME="/usr/local/jdk"
  6. def M2_HOME="/usr/local/maven"
  7. def MAVEN_OPTS="-Xmx1024m"
  8.  
  9. def PATH="/opt/kube/bin:/bin:/sbin/:/usr/bin:/usr/sbin/:/usr/local/bin:$PATH"
  10.  
  11. def dingding_url="https://oapi.dingtalk.com/robot/send?access_token=**************************"
  12.  
  13. def harbor_server="***************"
  14.  
  15. def harbor_auth_id="**********************"
  16.  
  17. def git_auth_id="*********************"
  18.  
  19. def ansible_repo="git@gitlab.*********************.git"
  20.  
  21. def app_repo="git@gitlab.*********************.git"
  22.  
  23. }
  24.  
  25. options {
  26. //默认是启用并发构建,disableConcurrentBuilds如果开启则为禁用并发构建
  27. // disableConcurrentBuilds()
  28. //保持构建的最大个数
  29. buildDiscarder(logRotator(numToKeepStr: ''))
  30. ansiColor('xterm')
  31. timestamps()
  32. }
  33.  
  34. parameters {
  35. choice(name: 'service_name', choices: '*********************')
  36. gitParameter(name: 'branch_name', branchFilter: 'origin/(.*)', defaultValue: 'master', type: 'PT_BRANCH', quickFilterEnabled: 'true', description: '选择需要构建的分支', sortMode: 'ASCENDING_SMART')
  37. }
  38.  
  39. post{
  40. success{
  41. script {
  42.  
  43. dingTalk accessToken: "${env.dingding_url}", imageUrl: '*********************', jenkinsUrl: "${env.BUILD_URL}",message: "应用${service_name}构建成功!",notifyPeople: '*********************'
  44.  
  45. wrap([$class: 'BuildUser']) {
  46. mail to: "${BUILD_USER_EMAIL}",
  47. from: "*********************",
  48. subject: "'${JOB_NAME}' 第${BUILD_NUMBER}次,构建结果通知【成功】",
  49. body: "本次构建由 ${BUILD_USER} 发起,构建【成功】,构建版本 ${params.service_name}:${params.branch_name} .\n具体构建细节,可以前往${env.BUILD_URL}进行查看。"
  50. }
  51.  
  52. }
  53.  
  54. cleanWs()
  55.  
  56. }
  57. failure{
  58. script {
  59.  
  60. dingTalk accessToken: "${env.dingding_url}", imageUrl: '*********************', jenkinsUrl: "${env.BUILD_URL}",message:"应用${service_name}构建失败!",notifyPeople: '*********************'
  61.  
  62. wrap([$class: 'BuildUser']) {
  63. mail to: "${BUILD_USER_EMAIL}",
  64. from: "*********************",
  65. subject: "'${JOB_NAME}' 第${BUILD_NUMBER}次,构建结果通知【失败】",
  66. body: "本次构建由 ${BUILD_USER} 发起,构建【失败】 ,构建版本 ${params.service_name}:${params.branch_name} .\n具体构建细节,可以前往${env.BUILD_URL}进行查看。"
  67. }
  68. }
  69. }
  70. unstable{
  71. script {
  72. wrap([$class: 'BuildUser']) {
  73. mail to: "${BUILD_USER_EMAIL}",
  74. from: "*********************",
  75. subject: "'${JOB_NAME}' 第${BUILD_NUMBER}次,构建结果通知【失败】",
  76. body: "本次构建由 ${BUILD_USER} 发起,构建【失败】,构建版本 ${params.service_name}:${params.branch_name} .\n具体构建细节,可以前往${env.BUILD_URL}进行查看。"
  77. }
  78. }
  79. }
  80. }
  81.  
  82. stages {
  83. stage("获取代码") {
  84. parallel{
  85. stage('配置构建信息') {
  86. steps {
  87. script {
  88. wrap([$class: 'BuildUser']){
  89. currentBuild.description = "本次构建由<strong><span style='color:#E53333;'> ${BUILD_USER} </span></strong>发起,构建版本 <strong><span style='color:#E53333;'>${params.service_name}:${params.branch_name}</span></strong>"
  90. }
  91. }
  92. }
  93. }
  94.  
  95. stage("获取应用代码") {
  96. steps {
  97. echo "branch_name: ${params.branch_name}"
  98. sh 'git config --global http.sslVerify false'
  99.  
  100. wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
  101. dir ( "${env.WORKSPACE}" ) {
  102. git (
  103. branch: "${params.branch_name}",
  104. credentialsId: "${env.git_auth_id}",
  105. url: "${app_repo}"
  106. )
  107. }
  108. }
  109. }
  110. }
  111.  
  112. }
  113. }
  114.  
  115. stage("jacoco覆盖率统计") {
  116. steps {
  117. dir("${env.WORKSPACE}") {
  118. sh "pwd"
  119. 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"
  120. jacoco(execPattern:'jacoco_payment.exec',classPattern:"${params.classPattern}",sourcePattern:"${params.sourcePattern}",exclusionPattern:"${params.exclusionPattern}")
  121.  
  122. }
  123. }
  124. }
  125. }
  126. }

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

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

好了  到此结束

功能+自动化测试代码扫描(demo)的更多相关文章

  1. Appium 从 0 到 1 搭建移动 App 功能自动化测试平台 (1):模拟器中运行 iOS 应用

    转载:https://testerhome.com/topics/4960 在上一篇文章中,我对本系列教程的项目背景进行了介绍,并对自动化测试平台的建设进行了规划. 在本文中,我将在已准备就绪的iOS ...

  2. SpringBoot集成mybatis以及自动化测试代码实现

    Mybatis和logback的应用配置 1.在module的pom.xml文件中,加载springboot和swagger.lombok.fastjson.mysql.mybatis包 2.在res ...

  3. 持续集成工具之jenkins+sonarqube做代码扫描

    上一篇我们主要聊了下代码质量管理平台sonarqube的安装部署以及它的工作方式做了简单的描述和代码扫描演示:回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13 ...

  4. 【Lua篇】静态代码扫描分析(一)初步介绍

    一.静态代码分析         静态代码分析是一种通过检查代码而不是执行程序来发现源代码中错误的手段.通常可以帮助我们发现常见的编码错误,例如: 语法错误 违反制定的标准编码 未定义的变量 安全性问 ...

  5. 初版storm项目全流程自动化测试代码实现

    由于项目需要,写了版针对业务的自动化测试代码,主要应用场景在于由于业务日趋复杂,一些公共代码的改动,担心会影响已有业务.还没进行重写,但知识点还是不少的与大家分享实践下.首先,介绍下整个流处理的业务流 ...

  6. 从0到1搭建移动App功能自动化测试平台(2):操作iOS应用的控件

    转自:http://debugtalk.com/post/build-app-automated-test-platform-from-0-to-1-Appium-interrogate-iOS-UI ...

  7. 从0到1搭建移动App功能自动化测试平台(0):背景介绍和平台规划

    本文作者: 伯乐在线 - debugtalk .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 转载地址:http://blog.jobbole.com/101221/ 背景 最近新加入DJI的 ...

  8. Coverity代码扫描工具

    1.说明:Coverity代码扫描工具可以扫描java,C/C++等语言,可以和jenkins联动,不过就是要收钱,jenkins上的插件可以用,免费的,适用于小的java项目 2.这是Coverit ...

  9. 使用OClint进行iOS项目的静态代码扫描

    使用OClint进行iOS项目的静态代码扫描 原文链接:http://blog.yourtion.com/static-code-analysis-ios-using-oclint.html 最近需要 ...

随机推荐

  1. Java实现 LeetCode 61 旋转链表

    61. 旋转链表 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: 1->2->3->4->5->NULL, k = ...

  2. java实现第七届蓝桥杯机器人塔

    机器人塔 X星球的机器人表演拉拉队有两种服装,A和B. 他们这次表演的是搭机器人塔. 类似: A B B A B A A A B B B B B A B A B A B B A 队内的组塔规则是: A ...

  3. PAT 反转链表

    给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转.例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4:如果 K 为 4,则输出应该 ...

  4. 美女面试官问我Python如何优雅的创建临时文件,我的回答....

    [摘要] 本故事纯属虚构,如有巧合,他们故事里的美女面试官也肯定没有我的美,请自行脑补... 小P像多数Python自学者一样,苦心钻研小半年,一朝出师投简历. 这不,一家招聘初级Python开发工程 ...

  5. Windows下虚拟机Linux(CentOS8)扩容设置 - 磁盘扩容中的坑和解决方法

    摘要:[原创]转载请注明作者Johnthegreat和本文链接 由于虚拟机空间不足,为了避免重装虚拟机,做了一次无损扩容.   过程中的报错如下: [root@localhost ~]# pvcrea ...

  6. AS中将module转成library的步骤

    转换步骤是在Android Studio 2.3版本下进行的,其他版本未测试 将要变成library的module的gradle文件的第一行 修改前:apply plugin: 'com.Androi ...

  7. windows tcp server select

    #include <stdio.h> #include <tchar.h> #include <winsock2.h> #include <iostream& ...

  8. Windows环境下PHP安装pthreads多线程扩展

    一.判断PHP是ts还是nts版 通过phpinfo(); 查看其中的 Thread Safety 项,这个项目就是查看是否是线程安全,如果是:enabled,一般来说应该是ts版,否则是nts版. ...

  9. PE文件介绍 (1)

    PE文件介绍 PE文件主要是windows操作系统下使用的可执行文件格式,PE文件是指32位的可执行文件也叫做PE32,64位可执行文件叫做PE+或者PE32+ PE文件格式 种类 主扩展名 可执行类 ...

  10. nacos基础--客户端下载

    对于nacos的作用,我在这里不在过多介绍,不知道的同学可以自行先了解,对于nacos,有官网进行介绍,对于一个初学者来说是一件非常方便的事情. 官网地址:https://nacos.io 但是在下载 ...