jenkins流水线整合jacoco与sonar(一)

jenkins流水线整合jacoco与sonar(一)

jacoco单元测试整合

1.项目引入jacoco依赖

   <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.2</version>
        </dependency>
            <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
           <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.2</version>
                <configuration>
                    <destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
                    <dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
                    <includes>
                        <!--指定检测的目录,请注意项目的控制层和服务层包命名是否和配置相同-->
                        <include>**/service/**</include>
                        <include>**/controller/**</include>
                    </includes>
                    <output>file</output>
                    <append>true</append>
                </configuration>
                <executions>
                    <execution>
                        <id>jacoco-initialize</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <phase>test-compile</phase>
                    </execution>

                    <execution>
                        <id>jacoco-site</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

2.jenkins流水线脚本编写

 stage('Unit Test') {
            if (enableUnitTest == "1") {
                println("#############################################开始单元测试##################################################")
                withEnv(["JAVA_HOME=/root/jenkins/tools/${jdkVersion}", "MVN_HOME=/root/jenkins/tools/maven3"]) {
                    sh '"$MVN_HOME/bin/mvn" clean jacoco:prepare-agent package jacoco:report'
                }
                //找到输出的xml文件,解析传入接口
                xmlOut = sh(script: "ls /root/jenkins/workspace/${jobName}/target/site/jacoco/jacoco.xml", returnStatus: true)
                //覆盖率文件存在
                if (xmlOut == 0) {
                    //将覆盖率文件复制到nginx
                    sh(script: "cp -r /root/jenkins/workspace/${jobName}/target/site/jacoco/  /root/unit_test/${jobName}_${pipeLineId}/")
                    def filePath = "target/site/jacoco/jacoco.xml"
                    def xmlContent = readFile file: filePath; encoding: "UTF-8"
                    println(xmlContent)
                    def toJson = {
                        input ->
                            groovy.json.JsonOutput.toJson(input)
                    }
                    def body = [
                            unitTestResultXml: "$xmlContent",
                            jobName          : "$jobName",
                            pipeLineId       : "$pipeLineId",
                            codeType         : "java"
                    ]
                    def response = httpRequest acceptType: 'APPLICATION_JSON', contentType: 'APPLICATION_JSON', httpMode: 'POST', requestBody: toJson(body), timeout: 10000, validResponseCodes: '100:599', url: "http://${host}${qualityApi}unitTest/getScoreResult"
                    println("unitTest Response:" + response)
                    println("response.data:" + response.content)
                    def responseBodyJson = readJSON text: response.content
                    def data = responseBodyJson.data
                    println(data)
                    if (response.status == 200) {
                        if (data.pass) {
                            println("#############单元测试通过#################")
                            println("##################################" + responseBodyJson.message + " 分支覆盖率:" + data.branchCoverage + "########################################")
                        } else {
                            println("##################################" + responseBodyJson.message + " 分支覆盖率:" + data.branchCoverage + "########################################")
                            sh "exit 1"
                        }
                    } else {
                        println("#############单元测试失败#################")
                        println("接口响应异常")
                        println(responseBodyJson)
                        sh "exit 1"
                    }
                }
                //覆盖率文件不存在
                else if (xmlOut == 2) {
                    println("#############单元测试失败#################")
                    println("##################################jacoco.xml不存在#############################");
                    println("请检查jacoco的相关依赖是否完整")
                    sh "exit 1"
                } else {
                    println("#############单元测试失败#################")
                    println("##################################命令有误,请检查#############################")
                    sh "exit 1"
                }
            } else {
                println("#############################################单元测试未启用,跳过单元测试##################################################")
            }
        }

  • 流水线语法可在jenkins 流水线语法的生成器中生成相应的demo脚本,再根据需要自己修改
  • jacoco脚本可在jacoco官网查到
  • 踩坑,发送post请求时,json数据转换先在脚本首行引入import groovy.json.JsonSlurper

3.jacoco扫描结果集成

执行流水线后,取到扫描结果调用对应的接口,解析相应的xml文件内容,解析时花了不少时间解决一系列坑,核心代码如下

 //截取<!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.1//EN" "report.dtd"> 解决解析报错
        StringBuilder builder = new StringBuilder(unitTestResultXml);
        int startIndex = builder.indexOf("<!");
        int endIndex = builder.indexOf(".dtd\">") + 6;
        unitTestResultXml = builder.replace(startIndex, endIndex, "").toString();
        //解析xml字符串内容
        Document document = null;
        try {
            document = DocumentHelper.parseText(unitTestResultXml);
        } catch (DocumentException e) {
            log.error("解析xml出错", e);
            throw new BusinessException(false, QualityEnum.XML_PARSE_EXCEPTION.getCode(), QualityEnum.XML_PARSE_EXCEPTION.getMassage());
        }
        Element rootElement = document.getRootElement();
        List elements = rootElement.elements("counter");
        Iterator iterator = elements.iterator();
        while (iterator.hasNext()) {
            Element element = (Element) iterator.next();
            //获取参数
             String type = element.attributeValue("type");
            int covered = Integer.parseInt(element.attributeValue("covered"));
            int missed = Integer.parseInt(element.attributeValue("missed"));
            double coverage = Double.parseDouble(String.valueOf(NumberUtil.mul(NumberUtil.roundStr(NumberUtil.div(covered, NumberUtil.add(covered, missed)), 2), "100")));
            if (type.equals(UnitTestAttributeEnum.BRANCH.getAttribute())) {
                unitTestResult.setBranchCovered(covered)
                        .setBranchMissed(missed)
                        .setBranchCoverage(coverage);
                break;
            }
        }
        return unitTestResult;

经讨论决定,只取了分支覆盖率作为评判标准,再根据不同级别的项目标准给出测试结果,至此jacoco的集成就完成了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值