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/**']) } } }
方案一的核心逻辑:
-Dmaven.test.failure.ignore=true:让Maven在测试失败时不终止,继续完成后续的报告生成等步骤,这样我们才能拿到完整的测试结果。junit步骤:Jenkins官方插件,会自动解析测试报告,返回的对象包含failures(失败用例数)、skips(跳过用例数)等字段,我们用这些来判断是否要标记为UNSTABLE。- 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
相关产品推荐
相关产品推荐

