You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JUnit测试失败时将Jenkins构建标记为Unstable的配置方法

实现Jenkins构建:测试失败标记为UNSTABLE,严重错误标记为FAILED

我来帮你调整Jenkinsfile,实现你想要的效果:当JUnit测试失败时把构建标记为UNSTABLE,只有遇到编译失败、依赖缺失这类严重错误时才标记为FAILED。

先说说你原来代码里的问题:你只捕获了AssertionError,但Maven在测试失败时会返回非0的退出码,触发的是Shell执行异常,根本不会走到这个catch块里,所以你的逻辑没法生效。下面给你两种可靠的解决方案:

方案一:推荐!用Maven参数+JUnit插件处理(更稳定)

这个方法让Maven在测试失败时继续完成构建流程,然后通过Jenkins的JUnit插件解析测试报告,精准判断状态。

完整的Jenkinsfile代码:

node {
    stage('Checkout') {
        checkout scm
    }

    stage('Build & Test') {
        try {
            // 关键参数-Dmaven.test.failure.ignore=true:测试失败不中断构建,继续生成报告
            sh '''
                mvn clean -B org.jacoco:jacoco-maven-plugin:prepare-agent install -Dmaven.test.failure.ignore=true
            '''
            
            // 解析JUnit测试报告,拿到失败/跳过的用例数
            def testResults = junit(
                testResults: '**/target/surefire-reports/*.xml',
                allowEmptyResults: false,
                keepLongStdio: true
            )
            
            // 根据测试结果设置构建状态
            if (testResults.failures > 0 || testResults.skips > 0) {
                currentBuild.result = 'UNSTABLE'
            } else {
                currentBuild.result = 'SUCCESS'
            }
        } catch (Exception e) {
            // 这里捕获的是严重错误:比如编译失败、Maven命令跑不起来(依赖下载失败、网络问题)
            currentBuild.result = 'FAILED'
            throw e // 可选:抛出异常让Jenkins显示具体失败原因
        } finally {
            // 这里补充你的Jacoco报告发布逻辑(你原来代码里的step)
            step([$class: 'JacocoPublisher',
                  execPattern: '**/target/jacoco.exec',
                  classPattern: '**/target/classes',
                  sourcePattern: '**/src/main/java',
                  exclusionPattern: '**/test/**'])
        }
    }
}

方案一的核心逻辑:

  1. -Dmaven.test.failure.ignore=true:让Maven在测试失败时不终止,继续完成后续的报告生成等步骤,这样我们才能拿到完整的测试结果。
  2. junit步骤:Jenkins官方插件,会自动解析测试报告,返回的对象包含failures(失败用例数)、skips(跳过用例数)等字段,我们用这些来判断是否要标记为UNSTABLE。
  3. catch块:只处理真正的严重错误,比如代码编译不通过、Maven命令执行失败(比如依赖找不到),这时候才标记为FAILED。

方案二:捕获异常并检查日志(适合不想让Maven继续执行的场景)

如果你不想让Maven在测试失败后继续跑后续步骤,可以捕获sh的异常,然后通过Maven的输出日志判断失败类型:

node {
    stage('Checkout') {
        checkout scm
    }

    stage('Build & Test') {
        def mavenLog = ''
        try {
            // 捕获Maven的输出日志
            mavenLog = sh(
                script: 'mvn clean -B org.jacoco:jacoco-maven-plugin:prepare-agent install',
                returnStdout: true
            )
            currentBuild.result = 'SUCCESS'
        } catch (Exception e) {
            // 检查日志里是否有测试失败的关键词
            if (mavenLog.contains('BUILD FAILURE') && mavenLog.contains('There are test failures')) {
                currentBuild.result = 'UNSTABLE'
            } else {
                // 其他严重错误,标记为FAILED
                currentBuild.result = 'FAILED'
                throw e
            }
        } finally {
            // 发布Jacoco报告
            step([$class: 'JacocoPublisher',
                  execPattern: '**/target/jacoco.exec',
                  classPattern: '**/target/classes',
                  sourcePattern: '**/src/main/java',
                  exclusionPattern: '**/test/**'])
        }
    }
}

方案二的注意点:

这种方式依赖Maven的日志内容,如果你的Maven版本不同,日志里的关键词可能有变化,稳定性不如方案一,所以优先推荐方案一。

内容的提问来源于stack exchange,提问作者Souad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:59:26