0

Not found any reference to this particular question.

I am looking to find a way to achieve something like this in a Jenkins pipeline which runs our acceptance tests using Protractor and Cucumber.js:

            steps {
                container('selenium') {
                    script {
                        try {
                             {
                                //run tests
                            }
                        }
                        catch (err) {
                            if (env.testFailed == 'true') {
                                println "A test failure exists - build status updated to failure"
                                currentBuild.result = 'FAILURE'
                                error "Test(s) have failed"
                            } 
                            else {
                                println "No test failures exist - build status updated to success"
                                currentBuild.result = 'SUCCESS'
                            }
                        }
                    }
                }
            }

This would fail the build if the env var of testFailed is 'true'. The reason for this is we are encountering bugs with Protractor-Cucumber framework where if a failed test retries and passes the exit code of the stage is still 1.

So in the After hook of each test I am setting the env var using node.js to true if the Scenario status is failed:

  if (scenario.result.status === Status.FAILED) {
    process.env.testFailed = 'true';
  }
  if (scenario.result.status === Status.PASSED) {
    process.env.testFailed = 'false';
  }

The problem I have found is that the Jenkins pipeline fails to read the env var value in the code block of the catch section. It is always null.

Any ideas?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Phonesis
  • 323
  • 3
  • 12
  • Does this answer your question? [Is it possible to change the Environment of a parent process in Python?](https://stackoverflow.com/questions/263005/is-it-possible-to-change-the-environment-of-a-parent-process-in-python) – omajid Feb 12 '20 at 21:55
  • Potentially, I think the idea of writing to a file might be my best bet – Phonesis Feb 13 '20 at 10:25

2 Answers2

2

1) change the After hook to write the true/false flag to a file in sync.

2) read the file in catch block

catch(err) {
   testFailed = sh(script:'cat result.flag.txt', returnStdout: true).trim()
   if(testFailed == 'true') {
      ...
   }

}

Another option if there is total/passed/failed case number in output of npm test

lines = []

try {
   lines = sh(script:'npm test', returnStdout: true).readLines();    
}
catch(err) {
   size = lines.size()

   // parse the last 20 lines to extract fail/pass/total number
   for(int i=size-20;i<size;i++) {
      line[i]
   } 
}
yong
  • 13,357
  • 1
  • 16
  • 27
  • Very nice idea, will try this out – Phonesis Feb 13 '20 at 10:23
  • So got an additional issue. Our tests run in parallel! So this file is often being overridden. So a test will fail and the file updates. But then another test will pass and overwrite the value and the pipeline will, wrongly, pass as a result! Any idea how to overcome this? – Phonesis Feb 14 '20 at 19:03
  • In the After hook, only when test fail to write the flag file, test pass won't do that. But you mentioned failed test will be retried, so I don't think mark the test result in After hook is a good option, I think parse the total/passed/failed cases number from the output of `npm test` in the catch is better. – yong Feb 15 '20 at 02:09
1

WHY IT DOESN'T WORK NOW?

I see that you're running your tests in a container. When you set an environment variable, it's reflected on the scope of your container not the Jenkins master server

WHAT YOU COULD TRY TO DO

This actually depends on how you run the tests, but this should be an option

// run tests here

// you should have a variable for your container
def exit_code = sh(script: "sudo docker inspect ${container.id} --format='{{.State.ExitCode}}'", returnStdout: true)

sh "exit ${exit_code}"

This actually also depends how you start the tests inside the container, So if you update your answer with this information I could help you

Sergey Pleshakov
  • 7,964
  • 2
  • 17
  • 40
  • Thanks Sergey, yong's answer has worked for me. So will use that I think. This is great info though. We start the tests via an NPM script command. – Phonesis Feb 14 '20 at 11:05