news 2026/6/13 7:32:39

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
功能测试+自动化测试代码覆盖率统计

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分支。后面可以选择对应的分支了

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

最后作为一位过来人也是希望大家少走一些弯路,在这里我给大家分享一些软件测试的学习资料,这些资料希望能给你前进的路上带来帮助。

视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 22:13:32

智能关机终极指南:让电脑在你睡觉时自动断电的完整方案

智能关机终极指南&#xff1a;让电脑在你睡觉时自动断电的完整方案 【免费下载链接】SteamShutdown Automatic shutdown after Steam download(s) has finished. 项目地址: https://gitcode.com/gh_mirrors/st/SteamShutdown 还在为深夜下载Steam游戏而不得不熬夜等待吗…

作者头像 李华
网站建设 2026/6/13 7:11:12

PS Vita内容管理深度解析:QCMA技术架构与实现原理

PS Vita内容管理深度解析&#xff1a;QCMA技术架构与实现原理 【免费下载链接】qcma Cross-platform content manager assistant for the PS Vita (No longer maintained) 项目地址: https://gitcode.com/gh_mirrors/qc/qcma 在PS Vita玩家的日常使用中&#xff0c;内容…

作者头像 李华
网站建设 2026/6/12 22:13:33

5分钟快速上手:在Windows上搭建企业级CentOS环境完整指南

5分钟快速上手&#xff1a;在Windows上搭建企业级CentOS环境完整指南 【免费下载链接】CentOS-WSL 项目地址: https://gitcode.com/gh_mirrors/ce/CentOS-WSL 想要在Windows系统上体验原汁原味的企业级CentOS Linux环境吗&#xff1f;CentOS-WSL项目为你提供了完美的解…

作者头像 李华
网站建设 2026/6/13 8:34:00

Mouseable:用键盘掌控鼠标的智能助手

Mouseable&#xff1a;用键盘掌控鼠标的智能助手 【免费下载链接】mouseable Mouseable is intended to replace a mouse or trackpad. 项目地址: https://gitcode.com/gh_mirrors/mo/mouseable 你是否曾想过摆脱鼠标的束缚&#xff0c;仅凭键盘就能完成所有操作&#x…

作者头像 李华
网站建设 2026/6/13 0:05:31

LunaTranslator终极指南:日文游戏实时翻译的完整解决方案

LunaTranslator终极指南&#xff1a;日文游戏实时翻译的完整解决方案 【免费下载链接】LunaTranslator Galgame翻译器&#xff0c;支持HOOK、OCR、剪贴板等。Visual Novel Translator , support HOOK / OCR / clipboard 项目地址: https://gitcode.com/GitHub_Trending/lu/Lu…

作者头像 李华
网站建设 2026/6/13 15:04:32

网易云音乐评论区:热门留言被IndexTTS 2.0读出制成彩蛋

网易云音乐评论区的“语音彩蛋”背后&#xff1a;IndexTTS 2.0 如何让 AI 声音更懂情绪 在网易云音乐的一首老歌播放间隙&#xff0c;突然传来一个温柔又熟悉的声音&#xff1a;“你当年写下的那句‘听这歌时我在哭’&#xff0c;现在有人替你读出来了。”这不是人工录音&#…

作者头像 李华