Jenkins单元测试


一.简介

每种编程语言都有自己的单元测试框架。执行单元测试的工作一般由构建工具来完成。Jenk-ins做的只不过是执行这些构建工具的单元测试命令,然后对测试报告进行收集,并呈现。

Jenkins并不会自动帮我们写单元测试,写单元测试还是要靠人。为什么要这样说呢?因为笔者发现,不少人认为Jenkins的自动化测试是指Jenkins代替人自动写测试。

二.单元测试

JUnit

JUnit是一个Java语言的单元测试框架,由Kent Beck和ErichGamma创建。当执行maven test命令时,Maven会执行测试阶段(包括单元测试),然后生成测试报告。

收集并展示JUnit测试报告的步骤如下:
1.安装Jenkins JUnit插件,搜junit

2.在Jenkins中加入junit步骤,通常将步骤放在post always中,因为当测试不通过时,我们依然可以收集到测试报告

post {
    always {
        junit testResults: "**/target/surefire-reports/*.xml"
    }
}

当pipeline运行结束后,在构建页的左边菜单栏及右边详情下都会多出一个链接:Test Result
file

3.单机“Test Result”进入,可以看到测试报告的详细信息
file

junit步骤的testResults参数支持Ant风格路径表达式。**/targetlsurefire-reports/*.xml表示只要是target/surefire-reports目录下的XML文件就会被当作JUnit测试报告处理,而不论target在哪个层级的目录下。

JacoCo

JUnit只是方便我们写单元测试的一个框架,但是并没有告诉我们有多少代码被测试覆盖到了。而JaCoCo填补了这一空白。JaCoCo是一个免费的Java代码覆盖率的库,能帮助我们检测出代码覆盖率,并输出覆盖率报告。

JaCoCo提供了以下几个维度的覆盖率分析。

  • 指令覆盖率( Instruction Coverage )
  • 分支覆盖率( Branch Coverage )
  • 圈复杂度覆盖率( Cyclomatic Complexity Coverage )
  • 行覆盖率( Line Coverage )
  • 方法覆盖率( Method Coverage )
  • 类覆盖率( Class Coverage )

以下是JaCoCo插件的使用步骤。
1.安装JaCoCo插件,搜索jacoco

2.在Maven项目中引入JaCoCo插件,执行maven jacoco生成代码覆盖率报告

<plugin>
    <groupId>org. jacoco</ groupId>
    <artifactId>jacoco- maven- plugin</ artifactId>
    <version>0.8.2</version>
    <executions>
        <execution>
            <id>prepare- agent</id>
            <goals>
                <goal>prepare - agent</ goal>
            </goals>
        </execution>
        <execution>
            < id>report</id>
            <phase>prepare - package</ phase>
            <goals>
                <goal>report</ goal>
            </goals>
        </execution>
        <execution>
            <id>post- unit - test</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
            <configuration>
                <!-- jacoco执行数据的文件路径- - >
                <dataFile>target/jacoco. exec</dataFile>
                <!--输出报告的路径-- >
                <outputDirectory>target/jacoco- ut</outputDirectory>
            </configuration>

        </execution>
    </executions>
    <configuration>
        <systemPropertyVariables>
            <jacoco- agent . destfile>target/jacoco. exec</jacoco- agent . destfile>
        </ systemPropertyVariables>
    </configuration>
</p1ugin>

3.使用jacoco步骤,在mvn命令之后执行,写法如下

steps{
    sh "mvn clean install”
    jacoco(
        //代码覆盖率统计文件位置,Ant风格路径表达式
        execPattern: ' target/**/* . exec', 

        // classes 文件位置,Ant风格路径表达式
        classPattern: ' target/classes',

        //源码文件位置,Ant风格路径表达式
        sourcePattern: ' src/main/java',

        //排除分析的位置,Ant风格路径表达式
        exclus ionPattern: 'src/test*',

        //是否禁用每行覆盖率的源文件显示
        skipCopyOfSrcFiles: false,

        //如果为true,则对各维度的覆盖率进行比较。如果任何一个维度的当前覆盖率小于最小覆盖率阈值,则构建状态为失败
        //如果当前覆盖率在最大阈值和最小阈值之间,则当前构建状态为不稳定;如果当前覆盖率大于最大阈值,则构建成功
        changeBuildStatus: true,

        //字节码指令覆盖率
        minimumInstructionCoverage: ' 30' , maximumInstructionCoverage: '70',

        //行覆盖率
        minimumLineCoverage: ' 30' ,maximumL ineCoverage: '70',

        //圈复杂度覆盖率
        minimumComplexityCoverage: ' 30' ,maximumComplexityCoverage:'70', 

        //方法覆盖率
        minimumMethodCoverage: ' 30' , maximumMethodCoverage:'70',

        //类覆盖率
        minimumClassCoverage: ' 30',maximumClassCoverage: ' 70',

        //分支覆盖率
        minimumBranchCoverage: ' 30' ,maximumBranchCoverage:'70',

        //如果为true,则只有所有维度的覆盖率变化量的绝对值小于相应的变化量阈值时,构建结果才为成功
        build0verBuild: true,
        
        //以下是各个维度覆盖率的变化量阈值
        deltaInstructionCoverage: ' 80',deltaLineCoverage: '80',
        deltaMethodCoverage: ' 80 ' ,deltaClassCoverage: '80',
        deltaComplexityCoverage: ' 80',deltaBranchCoverage: '80 '
    )
}

为了更好地理解jacoco步骤的参数,我们看看插件在自由风格项目中的UI
file

pipeline运行完成后,我们可以在任务详情页的下方看到报告。
file

buildOverBuild和changeBuildStatus参数都能影响Jenkins任务的结果状态,那么当这两个参数的值都为true时,结果由其共同决定

* Success AND Success = Success
* Unstable AND Unstable = Unstable
Failure AND Failure = Failure
X AND Failure = Failure, Failure AND X = Failure, X = Success/Unstable/Failure
* Y AND Unstable = Unstable, Unstable AND Y = Unstable, Y = Success/Unstable

最后,各个维度的覆盖率应该设置多少呢?没有标准答案。笔者的经验是先要确定项目是遗留的还是新建的。遗留的就以当前覆盖率为基线,新建的则设置相对高一些的要求。 再看项目的紧急程度,如果非常紧急的话,则可以考虑放低要求。最后看项目的重要程度,如果这个项目在整个架构中起着非常重要的作用,那么覆盖率要求会高一些。

三.总结

代码覆盖率越高,软件的质 量就越高吗?

我们来看看《软件之道:软件开发争议问题剖析》中是怎么说的:为了找到两者之间的关系,把WindowsVista(4000多万行代码、几千个二进制文件、数千名工程师)的分支覆盖率( Branch Coverage )与块覆盖率( Block Coverage )和其发布六个月内的现场缺陷对应起来。我们观察到覆盖率和质量之间有弱正相关性,预测查准率和查全率较差(查准率为83.8% ,查全率为54.8% )。

书中最终给出的答案是:代码覆盖率最好不要单独使用,而是需要与其他指标,如代码变动率、复杂度等一并考虑。所以,如果考虑将代码覆盖率作为团队开发人员的KPI,请慎重。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM