unstable build with unstable with
If mvn test
fails, it will return a non-zero exit code. In this case, the sh
step throws an AbortException
with "script returned exit code X", causing the Pipeline to stop executing, and being marked as FAILURE.
So, you need to find the Maven configuration that returns exit code 0
, even if there are test failures. Then the pipeline will continue, and you can parse the test results.
Or, you can check the exit code yourself, e.g. assuming that Maven returns an exit code 123
to denote test failures:
// Attempt to execute the testsint exitCode = sh script: 'mvn test', returnStatus: true// Check whether testing succeeded, or a known failure code was returnedif (exitCode == 0 || exitCode == 123) { // Attempt to parse the test results, if they exist junit '**/test-results-dir/TEST-*.xml' // At this point, the pipeline will have been marked as 'UNSTABLE', // assuming that parsing the results found at least one test failure} else { // Something unexpected happened (e.g. compile failure); stop pipeline. // This will cause the pipeline to be marked as 'FAILURE' error("Testing failed with exit code ${exitCode}.")}
I achieve the exact same behavior using the junit
step and the Maven option -Dmaven.test.failure.ignore=true
.
Here is an example from my Jenkinsfile :
stage('Build') { ... // Run Maven build and don't fail on errors withMaven( maven: 'Maven3', mavenSettingsConfig: 'provided-config-file') { sh "mvn clean install -Dmaven.test.failure.ignore=true" } // publish test results junit '**/target/surefire-reports/*.xml'}
The -Dmaven.test.failure.ignore=true
option make Maven to return 0 if tests failed, instead of 1.
If the return code of a command ran with sh
is different from 0, the build status is set to FAILED
and the build stops.
With this option, Maven returns 0 if tests failed, so the build proceeds to the next step.
The junit
step archive the tests results, and sets the build status to UNSTABLE
if some tests failed.
The following works, but there must be a better solution. I'm pretty disappointed with the pipeline support so far on Jenkins 2.19.2, it feels a bit half baked.
def runTests() { setTestStatus(sh (returnStatus: true, script: 'mvn clean test'))}@NonCPSdef setTestStatus(testStatus) { if (testStatus == 0) { currentBuild.result = 'SUCCESS' } else { def testResult = currentBuild.rawBuild.getAction(hudson.tasks.junit.TestResultAction.class) currentBuild.result = (testResult != null && testResult.failCount > 0) ? 'UNSTABLE' : 'FAILURE' }}