【问题标题】:How do I make Jenkins build fail when Maven unit tests fail?当 Maven 单元测试失败时,如何使 Jenkins 构建失败?
【发布时间】:2026-01-09 21:20:02
【问题描述】:

我正在使用 Jenkins、Maven 3.1 和 Java 1.6。我在 Jenkins 中设置了以下 Maven 作业,具有以下目标和选项...

clean install -U -P cloudbees -P qa

下面是我的 pom.xml surefire 配置...

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.17</version>
        <configuration>
                <reuseForks>true</reuseForks>
                <argLine>-Xmx2048m -XX:MaxPermSize=512M </argLine>
                <skipTests>false</skipTests>
        </configuration>
</plugin>

但是,当我的单元测试失败时,Jenkins 控制台输出仍然显示“BUILD SUCCESS”,并且构建被标记为“不稳定”而不是彻底失败。如果任何单元测试失败,我如何在 Jenkins(或 Maven,如果事实证明是这样的话)中配置东西,以便我的构建失败(不会变得不稳定或通过)?

以下是控制台输出的内容

17:08:04   MyProjectOrganizationControllerTest.testRecoverFromError » IllegalState Failed to...
17:08:04   MyProjectOrganizationControllerTest.testVerifyDistrictListPopulated » IllegalState
17:08:04   MyProjectOrganizationControllerTest.testUpdateSchool » IllegalState Failed to loa...
17:08:04   MyProjectOrganizationControllerTest.testDeleteSchool » IllegalState Failed to loa...
17:08:04   MyProjectOrganizationControllerTest.testVerifyOrgListPopulatedPrivateSchoolOrgType » IllegalState
17:08:04   MyProjectOrganizationControllerTest.testSubmitMultipleParams » IllegalState Faile...
17:08:04 
17:08:04 Tests run: 155, Failures: 0, Errors: 154, Skipped: 1
17:08:04 
17:08:04 [ERROR] There are test failures.
17:08:04 
17:08:04 Please refer to /scratch/jenkins/workspace/MyProject/MyProject/target/surefire-reports for the individual test results.
17:08:04 [JENKINS] Recording test results
17:08:07 log4j:WARN No appenders could be found for logger (org.apache.commons.beanutils.converters.BooleanConverter).
17:08:07 log4j:WARN Please initialize the log4j system properly.
17:08:14 [INFO] 
17:08:14 [INFO] --- maven-war-plugin:2.4:war (default-war) @ MyProject ---
17:08:15 [INFO] Packaging webapp
17:08:15 [INFO] Assembling webapp [MyProject] in [/scratch/jenkins/workspace/MyProject/MyProject/target/MyProject]
17:08:15 [INFO] Processing war project
17:08:15 [INFO] Copying webapp resources [/scratch/jenkins/workspace/MyProject/MyProject/src/main/webapp]
17:08:15 [INFO] Webapp assembled in [662 msecs]
17:08:15 [INFO] Building war: /scratch/jenkins/workspace/MyProject/MyProject/target/MyProject.war
17:08:20 [INFO] 
17:08:20 [INFO] --- maven-failsafe-plugin:2.17:integration-test (default) @ MyProject ---
17:08:20 [JENKINS] Recording test results
17:08:25 [INFO] 
17:08:25 [INFO] --- maven-failsafe-plugin:2.17:verify (default) @ MyProject ---
17:08:25 [INFO] Failsafe report directory: /scratch/jenkins/workspace/MyProject/MyProject/target/failsafe-reports
17:08:25 [JENKINS] Recording test results[INFO] 
17:08:25 [INFO] --- maven-install-plugin:2.4:install (default-install) @ MyProject ---
17:08:25 
17:08:25 [INFO] Installing /scratch/jenkins/workspace/MyProject/MyProject/target/MyProject.war to /home/jenkins/.m2/repository/org/mainco/subco/MyProject/76.0.0-SNAPSHOT/MyProject-76.0.0-SNAPSHOT.war
17:08:25 [INFO] Installing /scratch/jenkins/workspace/MyProject/MyProject/pom.xml to /home/jenkins/.m2/repository/org/mainco/subco/MyProject/76.0.0-SNAPSHOT/MyProject-76.0.0-SNAPSHOT.pom
17:08:26 Started calculate disk usage of build
17:08:26 Finished Calculation of disk usage of build in 0 seconds
17:08:26 Started calculate disk usage of workspace
17:08:26 Finished Calculation of disk usage of workspace in 0 seconds
17:08:26 [INFO] ------------------------------------------------------------------------
17:08:26 [INFO] BUILD SUCCESS
17:08:26 [INFO] ------------------------------------------------------------------------
17:08:26 [INFO] Total time: 11:00.616s
17:08:26 [INFO] Finished at: Mon Feb 23 17:08:26 UTC 2015
17:08:27 [INFO] Final Memory: 90M/414M
17:08:27 [INFO] ------------------------------------------------------------------------
17:08:27 Waiting for Jenkins to finish collecting data
17:08:28 [JENKINS] Archiving /scratch/jenkins/workspace/MyProject/MyProject/pom.xml to org.mainco.subco/MyProject/76.0.0-SNAPSHOT/MyProject-76.0.0-SNAPSHOT.pom
17:08:28 [JENKINS] Archiving /scratch/jenkins/workspace/MyProject/MyProject/target/MyProject.war to org.mainco.subco/MyProject/76.0.0-  SNAPSHOT/MyProject-76.0.0-SNAPSHOT.war
17:08:31 channel stopped
17:08:31 Started calculate disk usage of build
17:08:31 Finished Calculation of disk usage of build in 0 seconds
17:08:31 Started calculate disk usage of workspace
17:08:31 Finished Calculation of disk usage of workspace in 0 seconds
17:08:31 Finished: UNSTABLE

【问题讨论】:

    标签: maven jenkins maven-surefire-plugin jenkins-build-flow


    【解决方案1】:

    另一个有用的技巧是使用 groovy post-build 来检查和设置测试结果。

    例如这个 groovy 获取构建结果,将有用的东西附加到构建描述中,并在没有通过或失败但所有测试都跳过的情况下将构建结果设置为 UNSTABLE。

    def currentBuild = Thread.currentThread().executable
    // must be run groovy post-build action AFTER harvest junit xml  if you use junit xml test results
    testResult1 = currentBuild.testResultAction
    
    currentBuild.setDescription(currentBuild.getDescription() + "\n pass:"+testResult1.result.passCount.toString()+", fail:"+testResult1.result.failCount.toString()+", skip:"+testResult1.result.skipCount.toString())
    
    // if no pass, no fail all skip then set result to unstable
    if (testResult1.result.passCount == 0 && testResult1.result.failCount == 0 && testResult1.result.skipCount > 0) {
       currentBuild.result = hudson.model.Result.UNSTABLE
    }
    
    currentBuild.setDescription(currentBuild.getDescription() + "\n" + currentBuild.result.toString())
    
    def ws = manager.build.workspace.getRemote()
    myFile = new File(ws + "/VERSION.txt")
    desc = myFile.readLines()
    currentBuild.setDescription(currentBuild.getDescription() + "\n" + desc)
    

    【讨论】:

      【解决方案2】:

      如果您点击 Jenkins Job 的 Build 部分中的 Advanced 按钮,您可以将 -Dmaven.test.failure.ignore=false 添加到 MAVEN_OPTS

      请参阅Maven Surefire Plugin - surefire:test 选项以供参考。

      【讨论】:

      • 但是我们真的必须将此标志指定为 false 吗?根据我的理解,如果我们不指定此单位,则默认值仅为“FALSE”。请建议。谢谢!
      • Jenkins 默认将此值指定为 true。看看issues.jenkins-ci.org/browse/JENKINS-24655
      • 记住documentation告诉“不推荐使用它”
      • @Kai 要清楚,根据链接中的文档,不建议设置 -Dmaven.test.failure.ignore=true 。如果 Jenkins 将此设置为不推荐的值,则将其更改回 false 符合文档中警告的精神。
      • 但这并没有显示 Jenkins UI 中哪些测试失败了。
      【解决方案3】:

      使用Text Finder 插件。将其配置为查找There are test failures 并将构建降级为FAILED

      【讨论】:

      • 不错的 hack,但仍然是一个 hack。
      • 除了是一个黑客之外,我还发现它无法将 UNSTABLE 降级为 FAILED 构建。我认为这可能与记录的“重新分类仅适用于返回总体退出状态为零的构建”有关。
      • 对于 Jenkins 管道,我发现这个 hack 是唯一可管理的解决方案:在 try-finally 中使用 -Dmaven.test.failure.ignore=true 运行 mvn。终于有findText regexp: 'There are test failures', alsoCheckConsoleOutput: true, unstableIfFound: truejunit allowEmptyResults: true, testResults: 'target/surefire-reports/*.xml'