0

I'm using Jenkins in a multi-modular Maven project and I have three stages in my pipeline: build, test and deploy. I want to be able to run all unit tests during test stage and, when there are test failures, deploy stage should be skipped.

For now, I managed to find a workaround (which works as I want it to), but I had to explicitly approve usage of some methods, which are marked by Jenkins as vurnelabilities.

I am wondering if there is any clearer way to achieve my goals?

import hudson.tasks.test.AbstractTestResultAction

pipeline {
    agent {
        docker {
            image 'maven:3-jdk-8-alpine'
            args '--name maven3 -v /root/.m2:/root/.m2'
        }
    }
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean install -DskipTests'
            }
        }

        stage('Test') {
            steps {
                sh 'mvn test --fail-never'
            }
            post {
                always {
                    junit '**/target/surefire-reports/*.xml'
                }
            }
        }

        stage('Deploy') {
            steps {
                script {
                    def AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
                    if (testResultAction == null) {
                        error("Could not read test results")
                    }
                    def numberOfFailedTests = testResultAction.failCount
                    testResultAction = null
                    if (numberOfFailedTests == null || numberOfFailedTests != 0) {
                        error("Did not deploy. Number of failed tests: " + numberOfFailedTests)
                    }
                    sh 'mvn deploy -DskipTests'
                }
            }
        }
    }
}
dominikbrandon
  • 408
  • 4
  • 16
  • Your build stage and Test stage duplicating several things based on the life cycle of Maven which means you should make a single Stage which will do the build and running of unit/integration tests... I would do `mvn --fail-at-end -e -B clean verify` cause I doubt that you need an `mvn install` ... furthermore if your really like to do a deploy than really do a single stage `mvn --fail-at-end -e -B clean deploy` and that's it....Deploy means only artifacts will be transfered to a repository manager .... – khmarbaise Sep 14 '18 at 13:14
  • Well, my project is multi-modular and `--fail-at-end` results in skipping tests from modules that depend on the failing module. Which is not what I want it to do, as I need results of all tests in my project. – dominikbrandon Sep 15 '18 at 14:09

1 Answers1

0

In your test stage you execute: mvn test --fail-never

Now even if you have test failures maven will return with an exit code 0.

Jenkins is checking the exit code. if it is 0 it will continue with the next command.

so get rid of --fail-never

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
wirnse
  • 1,026
  • 8
  • 7
  • My project has many modules and I strictly want to execute all tests along them. – dominikbrandon Oct 25 '18 at 07:28
  • One idea i found at [how-to-compile-all-maven-modules-even-if-tests-fail-but-fail-overall-build-if-a](https://stackoverflow.com/questions/23833589/how-to-compile-all-maven-modules-even-if-tests-fail-but-fail-overall-build-if-a) is to first call `mvn test --fail-never` and then `mvn test`. Which isn't very pretty. I think your way by checking the test results of the current build is a good one. – wirnse Oct 28 '18 at 11:45
  • Another idea maybe worth to try is to set the option `options { skipStagesAfterUnstable() }`. When `junit` is called and there a test failures it should mark the build as unstable. – wirnse Oct 28 '18 at 12:17