Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to aggregate test results in jenkins parallel pipeline?

I have a Jenkinsfile with a definition for parallel test execution, and the task is to grab the test results from both in order to process them in a post step somewhere.

Problem is: How to do this? Searching for anything acting as an example code does not bring up anything - either the examples deal with explaining parallel, or they explain post with junit.

pipeline {
    agent { node { label 'swarm' } }

    stages {
        stage('Testing') {
            parallel {
                stage('Unittest') {
                    agent { node { label 'swarm' } }

                    steps {
                        sh 'unittest.sh'
                    }
                }

                stage ('Integrationtest') {
                    agent { node { label 'swarm' } }

                    steps {
                        sh 'integrationtest.sh'
                    }
                }
            }
        }
    }
}

Defining a post {always{junit(...)}} step at both parallel stages yielded a positive reaction from the BlueOcean GUI, but the test report recorded close to double the amount of tests - very odd, some file must have been scanned twice. Adding this post step to the surrounding "Testing" stage gave an error.

I am missing an example detailing how to post-process test results that get created in a parallel block.

like image 941
Sven Avatar asked Nov 13 '17 15:11

Sven


2 Answers

Just to record my solution for the internet:

I came up with stashing the test results in both parallel steps, and adding a final step that unstashes the files, then post-processes them:

pipeline {
    agent { node { label 'swarm' } }

    stages {
        stage('Testing') {
            parallel {
                stage('Unittest') {
                    agent { node { label 'swarm' } }

                    steps {
                        sh 'rm build/*'
                        sh 'unittest.sh'
                    }
                    post {
                        always {
                            stash includes: 'build/**', name: 'testresult-unittest'
                        }
                    }

                }

                stage ('Integrationtest') {
                    agent { node { label 'swarm' } }

                    steps {
                        sh 'rm build/*'
                        sh 'integrationtest.sh'
                    }

                    post {
                        always {
                            stash includes: 'build/**', name: 'testresult-integrationtest'
                        }
                    }
                }
            }
        }

        stage('Reporting') {
            steps {
                unstash 'testresult-unittest'
                unstash 'testresult-integrationtest'
            }

            post {
                always {
                    junit 'build/*.xml'
                }
            }
        }
    }
}

My observation though is that you have to pay attention to clean up your workspace: Both test stages do create one file, but on the second run, both workspaces are inherited from the previous run and have both previously created test results present in the build directory.

So you have to remove any remains of test results before you start a new run, otherwise you'd stash an old version of the test result from the "other" stage. I don't know if there is a better way to do this.

like image 79
Sven Avatar answered Nov 07 '22 11:11

Sven


To ensure the stage('Reporting') will be always executed, put all the step in the 'post':

post {
    always {
        unstash 'testresult-unittest'
        unstash 'testresult-integrationtest'
        junit 'build/*.xml'
    }
}
like image 28
MathieuB28 Avatar answered Nov 07 '22 11:11

MathieuB28