测试覆盖率 服务端代码覆盖率统计入门

xinxi · 2019年05月20日 · 最后由 回复于 2019年12月02日 · 525 次阅读

前言

一直以来的工作重心和工作发展都是在移动端上,服务端的东西虽然不能说不会,但是也达不到精通.所以在闲暇的时候也会学习一下服务端的框架和基本知识.

个人认为现在的测试工程师应该是具有多纬度能力和深度学习能力的.比如多维度应该学习不同纬度的技能,如移动端、服务端、自动化框架、内部平台建设、监控体系、精准测试.对多维度技能都入门或者大概了解后,再深挖一个方向去钻研.

本文大致讲述"服务端代码覆盖率统计"的环境搭建和入门,另外也算是最近学习的一个总结.

jacoco + ant + spring boot + SonarQube

环境介绍

  • jacoco 是一个开源的覆盖率工具,通过插桩方式来记录代码执行轨迹.

  • ant 是构建工具,内置任务和可选任务组成的.Ant 运行时需要一个 XML 文件 (构建文件)。

  • Spring Boot 是一个轻量级 java web 框架,可以完成基于 Spring 的应用程序的大部分配置工作.

  • SonarQube 是一个用于管理源代码质量开放平台,它可以从多个维度检测代码质量,可以快速的定位代码中潜在的或者明显的 Bug、错误.

覆盖率统计工具对比

这块的工具对比和相关原理介绍可以参考有赞测试浅谈代码覆盖这篇帖子,原理和工具讲的比较透彻,本文就不做过多介绍了.

image

流程

  • 启动服务携带 jacocoagent 参数

  • 生成 jacoco.exec

  • ant 任务生成覆盖率报告

  • 上传到 SonarQube 平台展示

image

配置 ant

下载地址:https://ant.apache.org/bindownload.cgi

image

下载完成后并配置 ant 环境变量

vim .bash_profile
export ANT_HOME=/Users/xinxi/Documents/apache-ant-1.9.14
export PATH=${PATH}:${ANT_HOME}/bin
source .bash_profile

输入"ant -version"检查是否安装成功.

配置 build.xml

build.xml 放到~/Documents/apache-ant-1.9.14/bin 路径下

<?xml version="1.0" encoding="UTF-8"?>
<project name="test" xmlns:jacoco="antlib:org.jacoco.ant" >
    <!--Jacoco的安装路径-->
  <property name="jacocoantPath" value="/Users/xinxi/Documents/jacoco-0.8.3/lib/jacocoant.jar"/>
  <!--最终生成.exec文件的路径,Jacoco就是根据这个文件生成最终的报告的-->
  <property name="jacocoexecPath" value="/Users/xinxi/Documents/jacoco-0.8.3/target/jacoco.exec"/>
    <!--生成覆盖率报告的路径-->
  <property name="reportfolderPath" value="/Users/xinxi/Documents/jacoco-0.8.3/report"/>
  <!--远程tomcat服务的ip地址-->
  <property name="server_ip" value="127.0.0.1"/>
  <!--前面配置的远程tomcat服务打开的端口,要跟上面配置的一样-->
  <property name="server_port" value="6300"/>
  <!--源代码路径可以包含多个源代码-->   
  <property name="checkOrderSrcpath" value="/Users/xinxi/Documents/ideaProjcet/springboot-learning-example/springboot-webflux-1-quickstart/src/main/java/" />   

  <!--.class文件路径可以包含多个-->
  <property name="checkOrderClasspath" value="/Users/xinxi/Documents/ideaProjcet/springboot-learning-example/springboot-webflux-1-quickstart/target/classes"/>


  <!--让ant知道去哪儿找Jacoco-->
  <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
      <classpath path="${jacocoantPath}" />
  </taskdef>

  <!--dump任务:
      根据前面配置的ip地址,和端口号,
      访问目标tomcat服务,并生成.exec文件。-->

  <target name="dump">
      <jacoco:dump address="${server_ip}" reset="true" destfile="${jacocoexecPath}" port="${server_port}" append="false"/>
  </target>

   <!--jacoco任务:
      根据前面配置的源代码路径和.class文件路径,
      根据dump后,生成的.exec文件,生成最终的html覆盖率报告。-->
  <target name="report">
      <delete dir="${reportfolderPath}" />
      <mkdir dir="${reportfolderPath}" />

      <jacoco:report>
          <executiondata>
              <file file="${jacocoexecPath}" />
          </executiondata>

          <structure name="JaCoCo Report">
              <group name="Check Order related">          
                  <classfiles>
                      <fileset dir="${checkOrderClasspath}" />
                  </classfiles>
                  <sourcefiles encoding="utf-8">
                      <fileset dir="${checkOrderSrcpath}" />
                  </sourcefiles>
              </group>
          </structure>
          <html destdir="${reportfolderPath}" encoding="utf-8" />        
      </jacoco:report>
  </target>
</project>

打包服务

spring boot 的代码地址:

git clone https://github.com/SuperHulk/springboot-learning-example.git

使用"quickstart"这个项目作为构建服务.

image

在项目根目录下,执行 mvn package 打包成 jar 包.

image

jacoco 下载

官方下载地址

https://www.eclemma.org/jacoco/

image

启动 jcocoagent

javaagent:javaagent 是 JDK 1.5 以后引入的,也可以叫做 Java 代理.
后面跟的参数是 jcocoagent 的 jar 包地址.

includes:包含在执行分析中的类名列表,* 表示全部.

output:表示使用 tcpserver 代理侦听由 address 和 port 属性指定的 TCP 端口,并将执行的数据写入此 TCP 连接,从而实现不停止项目运行实时生成代码覆盖率报告.

port:开启的端口号.

address: 开启的 ip 地址,本地写 127.0.0.1.

jar:运行服务的 jar 包地址.

java -javaagent:/Users/xinxi/Documents/jacoco-0.8.3/lib/jacocoagent.jar=includes=*,output=tcpserver,port=6300,address=127.0.0.1 \
-jar /Users/xinxi/Documents/ideaProjcet/springboot-learning-example/springboot-webflux-1-quickstart/target/springboot-webflux-1-quickstart-0.0.1-SNAPSHOT.jar

测试

测试两个接口的逻辑代码.

curl http://127.0.0.1:8080/hellocity

curl http://127.0.0.1:8080/hellocountry

生成报告

  • 在~/Documents/apache-ant-1.9.14/bin 下执行"ant dump"
  • 在~/Documents/jacoco-0.8.3/target 下生成"jacoco.exec"
  • 在~/Documents/apache-ant-1.9.14/bin 下执行"ant report"

image

打开"index.html"报告,展示类的覆盖率文件.

image

展示类中的代码覆盖范围.

image

展示类中的代码未覆盖范围.

image

sonar 配置

sonar 的 ant 插件下载

SonarQube Scanner for Ant 的官方文档.

https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Ant

image

配置 sonar.java.binaries

如果未配置 sonar.java.binaries 会出现如下报错,在 xml 中加入如下配置即可.

org.sonar.squidbridge.api.AnalysisException: Please provide compiled classes of your project with sonar.java.binaries property

image

增加配置

#添加下面这行
sonar.java.binaries=项目路径/target/classes

配置 sonar 的 xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project name="My Project" default="all" basedir="/Users/xinxi/Documents/ideaProjcet/springboot-learning-example/springboot-webflux-1-quickstart/" xmlns:sonar="antlib:org.sonar.ant">

    <!-- ========= Define the main properties of this project ========= -->
    <property name="src.dir" value="src" />
    <!-- <property name="test.dir" value="src" /> -->
    <property name="lib.junit.dir" value="lib" />
    <property name="build.dir" value="target" />
    <property name="target.dir" value="target" />
    <property name="classes.dir" value="${build.dir}/classes" />
    <property name="reports.dir" value="${build.dir}/reports" />
    <property name="reports.junit.xml.dir" value="${reports.dir}/junit" />

    <!-- Define the Sonar properties -->
    <property name="sonar.projectKey" value="jacoco_test" />
    <property name="sonar.projectName" value="jacoco test project" />
    <property name="sonar.projectVersion" value="1.0" />
    <property name="sonar.language" value="java" />
    <property name="sonar.sources" value="${src.dir}" />
    <!-- <property name="sonar.tests" value="${test.dir}" /> -->
    <property name="sonar.binaries" value="${classes.dir}" />
    <property name="sonar.java.binaries" value="${classes.dir}" />
    <property name="sonar.sourceEncoding" value="UTF-8" />
    <property name="sonar.surefire.reportsPath" value="${reports.junit.xml.dir}" /> 

    <!-- The following properties are required to use JaCoCo: -->
    <property name="sonar.dynamicAnalysis" value="reuseReports" />
    <property name="sonar.java.coveragePlugin" value="jacoco" />
    <property name="sonar.jacoco.reportPath" value="/Users/xinxi/Documents/jacoco-0.8.3/target/jacoco.exec" />

    <!-- Add your basic Sonar configuration below: sonar.jdbc.url, sonar.jdbc.username, etc. properties -->
    <property name="sonar.jdbc.url" value="jdbc:h2:tcp://localhost:9092/sonar" />
    <property name="sonar.jdbc.username" value="admin" />
    <property name="sonar.jdbc.password" value="admin" />

    <!-- ========= Define Sonar target ========= -->
    <target name="sonar">
        <taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml">
            <!-- Update the following line, or put the "sonar-ant-task-*.jar" file in your "$HOME/.ant/lib" folder -->
            <classpath path="/Users/xinxi/Documents/jacoco-0.8.3/lib/sonarqube-ant-task-2.6.0.1426.jar" />
        </taskdef>

        <!-- Execute Sonar -->
        <sonar:sonar />
    </target>

    <!-- ========= The main target "all" ========= -->
    <target name="all" depends="sonar" />

</project>

执行命令

ant -find sonar.xml 或者 ant sonar

控制台出现"BUILD SUCCESSFUL"说明执行成功

image

SonarQube 展示

SonarQube 搭建

使用 docker 搭建比较简单,启动命令如下.

docker run -d --name sonarqube -p 9000:9000 -p 9092:9092 sonarqube:lts
浏览器打开:0.0.0.0:9000
帐号密码:admin、admin

覆盖率展示

登录 sonar 查看数据结果,上传 sonar 的意义在于数据汇总,方便多人在线查看数据.

image

覆盖代码行

image

未覆盖代码行

image

结语

本文仅是简单的介绍了服务端的代码覆盖率统计,其中也包含了多个工具和知识点串联起来.

相关帖子

有赞测试浅谈代码覆盖率

https://testerhome.com/articles/16981?order_by=created_at&

Maven – JaCoCo code coverage example

https://www.mkyong.com/maven/maven-jacoco-code-coverage-example/

spring boot 项目集成 jacoco

http://www.pianshen.com/article/2705317982/

linux 下 jacoco 动态统计覆盖率

https://testerhome.com/topics/5329

https://www.jacoco.org/jacoco/trunk/doc/faq.html

spring boot 项目部署到服务器两种方式

https://blog.csdn.net/qq_22638399/article/details/81506448

ant 官方文档

http://ant.apache.org/manual/index.html

springboot 教程

http://springboot.fun

https://www.jacoco.org/jacoco/trunk/doc/cli.html

共收到 5 条回复 时间 点赞

消灭 0 回复,感谢作者分享!

学习了,感谢楼主分享

学习了

checkOrderSrcpath 这个地方为什么不是相对目录? 你们在 k8s 上 怎么 设置这个属性呢?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册