一、关于SonarQube

1、SonarQube的介绍

SonarQube 是一个用于代码质量管理的开源平台,用于管理源代码的质量。 通过插件形式,可以支持包括 java, C#,,C/C++, PL/SQL,
Cobol, JavaScrip, Groovy等等二十几种编程语言的代码质量管理与检测。

2、SonarQube的作用

➢不遵循代码标准
sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具规范代码编写。

➢潜在的缺陷
sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具检 测出潜在的缺陷。

➢糟糕的复杂度分布
文件、类、方法等,如果复杂度过高将难以改变,这会使得开发人员 难以理解它们, 且如果没有自动化的单元测试,对于程序中的任何组件的改变都将可能导致需要全面的回归测试。

➢重复
显然程序中包含大量复制粘贴的代码是质量低下的,sonar可以展示 源码中重复严重的地方。

➢注释不足或者过多
没有注释将使代码可读性变差,特别是当不可避免地出现人员变动 时,程序的可读性将大幅下降 而过多的注释又会使得开发人员将精力过多地花费在阅读注释上,亦违背初衷。

➢缺乏单元测试
sonar可以很方便地统计并展示单元测试覆盖率。

➢糟糕的设计
通过sonar可以找出循环,展示包与包、类与类之间的相互依赖关系,可以检测自定义的架构规则 通过sonar可以管理第三方的jar包,可以利用LCOM4检测单个任务规则的应用情况, 检测耦合。

二、关于JaCoCo

1、JaCoCo的介绍

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

2、JaCoCo覆盖率

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

➢ Instructions:Jacoco 计算的最小单位就是字节码指令。指令覆盖率表明了在所有的指令中,哪些被执行过以及哪些没有被执行。这项指数完全独立于源码格式并且在任何情况下有效,不需要类文件的调试信息。

➢ Branches:Jacoco 对所有的 if 和 switch 指令计算了分支覆盖率。这项指标会统计所有的分支数量,并同时支出哪些分支被执行,哪些分支没有被执行。这项指标也在任何情况都有效。异常处理不考虑在分支范围内。
在有调试信息的情况下,分支点可以被映射到源码中的每一行,并且被高亮表示。 红色钻石:无覆盖,没有分支被执行。 黄色钻石:部分覆盖,部分分支被执行。 绿色钻石:全覆盖,所有分支被执行。

➢ Cyclomatic Complexity:Jacoco 为每个非抽象方法计算圈复杂度,并也会计算每个类、包、组的复杂度。根据 McCabe 1996 的定义,圈复杂度可以理解为覆盖所有的可能情况最少使用的测试用例数。这项参数也在任何情况下有效。

➢ Lines:该项指数在有调试信息的情况下计算。
因为每一行代码可能会产生若干条字节码指令,所以我们用三种不同状态表示行覆盖率 红色背景:无覆盖,该行的所有指令均无执行。 黄色背景:部分覆盖,该行部分指令被执行。 绿色背景:全覆盖,该行所有指令被执行。

➢ Methods:每一个非抽象方法都至少有一条指令。若一个方法至少被执行了一条指令,就认为它被执行过。因为 Jacoco 直接对字节码进行操作,所以有些方法没有在源码显示(比如某些构造方法和由编译器自动生成的方法)也会被计入在内。

➢ Classes:每个类中只要有一个方法被执行,这个类就被认定为被执行。同 5 一样,有些没有在源码声明的方法被执行,也认定该类被执行。

三、推荐方案


方案概述:

通过检测代码提交,从gitLab拉取项目代码进行CI/CD编译build,执行单元测试,并依赖jacoco检测单元测试的覆盖率形成报告,触发Sonar Scanner扫描分析,同时上传到sonar服务器

1、开发人员在编写并提交代码(最好再IDE中集成sonarlint插件,并在本地进行代码分析检测,减少更多的缺陷代码被集成到SCM上)
2、SCM通过webhook调用,触发CI持续集成,CI触发Sonar Scanner,将本地代码进行扫描分析,输出分析报告,并发送给SonarQube服务端
3、SonarQube接受分析报告并处理,最终渲染到UI界面


项目实际配置操作:

1、单元测试

idea+maven+testng(或者JUnit或者其他单元测试框架)

Step 1、在pom.xml中配置maven插件和testng依赖,build添加jacoco插件
<dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

   <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <skip>false</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.10</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

step2~step4,可本地执行,并查看代码覆盖率报告

step5,因为已集成gitLab的CI/CD,所以不需要手动上传报告
Step 2、输入命令:mvn install,构建成功
Step 3、进入/target/site/jacoco/jacoco-resources/index.html查看汇总报告
Step 4、查看代码覆盖率检测报告
打开/target/site/jacoco/jacoco-resources/index.html,

可以看到覆盖率计数器,包含指令级(Instructions,C0 coverage),分支(Branches,C1 coverage)、圈复杂度(Cyclomatic Complexity)、行(Lines)、方法(Non-abstract Methods)、类(Classes),绿色代表覆盖,红色代表未覆盖

Step 5、执行命令,报告上传sonar

mvn clean verify sonar:sonar   
-Dsonar.projectKey=jacoco-test   
-Dsonar.host.url=http://192.168.21.200:9000   
-Dsonar.login=admin   
-Dsonar.password=zBrvVckjGyVXh8ua 
-Dsonar.java.coveragePlugin=jacoco
-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml

2、sonar+gitLab进行CI/CD

2.1、创建GitLab配置
2.1.1、sonar配置->ALM集成→GitLab,点击:创建配置

2.1.2、填写配置内容

配置名称:起一个名字(无要求,最好见名知意)

GitLab 网址:https://gitlab.trade.jianshicha.cn/api/v4 (公司Git地址)

个人访问令牌:********(为gitlab生成的令牌,下一步会讲到)

2.1.3、配置成功后,会检测配置是否正确。

成功的话,如上图。

2.2、GitLab添加个人访问令牌
2.2.1、用户设置->Access tokens

填写内容

令牌名称:起一个名字(无要求,最好见名知意)

到期时间:选择日期

选择范围:勾选api

点击:确认创建个人令牌。

2.2.2、创建成功

点击查看标识,可查看令牌,copy下来并保存好。后面无法再查看了。

(此令牌,会在sonar创建配置的时候用到,填写到sonar个人访问令牌中)

3、sonar新增项目

3.1、项目->新增项目->GitLab

3.2、点击:GitLab,会展示GitLab中的项目,如下图

3.3、点击设置,进入设置操作步骤
3.3.1、设置项目编码,选择:Maven
3.3.2、copy内容加入 pom.xml 文件中

<properties>
  <sonar.qualitygate.wait>true</sonar.qualitygate.wait>
</properties>

3.4、点击继续,添加环境变量,如图

3.4.1、点击创建令牌,选择过期时间,点击创建

3.4.2、令牌创建成功,copy并保存,后面gitLab上设置变量会用。

4、GitLab设置CI/CD

4.1、打开gitLab,选择对应的项目->设置->CI/CD

4.2、找到变量,展开内容后,点击:添加变量

4.3、新增变量
      • 在  字段,输入 SONAR_TOKEN
      • 在 数值 字段,输入 令牌(上面提到新生成保存的令牌)
      • 取消 保护变量 复选框
      • 保存变量

再次新增变量

      • 在  字段,输入 SONAR_HOST_URL
      • 在 数值 字段,输入 http://192.168.21.200:9000 (sonar的地址)
      • 取消 保护变量 复选框
      • 保存变量

5、创建或修改配置文件

项目中新建.gitlab-ci.yml,copy内容添加到.gitlab-ci.yml文件中。

如果已有.gitlab-ci.yml需要更新内容。

内容:

sonarqube-check:
  image: maven:3.6.3-jdk-11
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
    GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script: 
    - mvn verify sonar:sonar -Dsonar.projectKey=sun_testdemo3_AZOzjZPU_b62ofd11Uz7
  allow_failure: true
  only:
    - merge_requests
    - main
    - develop
    - test_20241212

如下图:

更改script脚本,在原本脚本中后面补充上:-Dsonar.java.coveragePlugin=jacoco -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml

script:
- mvn verify sonar:sonar -Dsonar.projectKey=sun_testdemo2_AZOvwTfW_b62ofd11Uzo -Dsonar.java.coveragePlugin=jacoco -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml

新增参数说明:通过jacoco检查覆盖率,并上传报告到sonar服务器(不增加的话,sonar上不会展示单元测试覆盖率)

脚本中only参数说明:可添加对应的分支名称,在对应分支提交代码时,会scanner对应分支的代码,出具报告。

after_script:
- echo "SonarQube report:http://192.168.21.200:9000/dashboard?id=sun_testdemo_AZOvNuNp_b62ofd11UzF"

id:为对应的projectKey。

可在后续gitLab流水线中直接查看sonarqube中的报告。点击report链接,直接跳转到sonar的报告结果页面。

6、GitLab中CI/CD配置runner

runner用于接收和执行GitLab的CI/CD作业

注册runner,当前已配置公共runner。需要运维支持。

Runner用于接收和执行GitLab的CI/CD作业的进程。有代码提交,就会自动CI/CD,触发流水线,自动编译

四、gitLab流水线项目build success后,sonar单元测试结果展示

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐