How to access Junit test counts in Jenkins Pipeline project How to access Junit test counts in Jenkins Pipeline project jenkins jenkins

How to access Junit test counts in Jenkins Pipeline project


For anyone coming here in 2020, there appears to be a simpler way now. The call to 'junit testResults' returns a TestResultSummary object, which can be assigned to a variable and used later.

As an example to send the summary via slack:

def summary = junit testResults: '/somefolder/*-reports/TEST-*.xml'slackSend (   channel: "#mychannel",   color: '#007D00',   message: "\n *Test Summary* - ${summary.totalCount}, Failures: ${summary.failCount}, Skipped: ${summary.skipCount}, Passed: ${summary.passCount}")


From this presentation of Cloudbees I found that it should be possible via "build" object.It has code like

def testResult = build.testResultActiondef total = testResult.totalCount

But currentBuild does not provide access to testResultAction.

So kept searching and found this post "react on failed tests in pipeline script".There Robert Sandell has given "pro tip"

Pro tip, requires some "custom whitelisting":

AbstractTestResultAction testResultAction =  currentBuild.rawBuild.getAction(AbstractTestResultAction.class)if (testResultAction != null) {    echo "Tests: ${testResultAction.failCount} / ${testResultAction.failureDiffString} failures of ${testResultAction.totalCount}.\n\n" }

This worked like a charm - just that I had to deselect "Groovy sandbox" checkbox.Now I have these in the build log

Tests: 11  / ±0 failures of 2624

Now I will use this to prepare string to notify in slack with test results.


UPDATE:

Finally, the function I used to get output like the following(Note the "failure diff" after failed tests is very useful)

Test Status:  Passed: 2628, Failed: 6  / ±0, Skipped: 0

Is the following:

import hudson.tasks.test.AbstractTestResultAction@NonCPSdef testStatuses() {    def testStatus = ""    AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)    if (testResultAction != null) {        def total = testResultAction.totalCount        def failed = testResultAction.failCount        def skipped = testResultAction.skipCount        def passed = total - failed - skipped        testStatus = "Test Status:\n  Passed: ${passed}, Failed: ${failed} ${testResultAction.failureDiffString}, Skipped: ${skipped}"        if (failed == 0) {            currentBuild.result = 'SUCCESS'        }    }    return testStatus}

UPDATE 2018-04-19

Note the above require manual "whitelisting" of methods used.Here is how you can whitelist all the methods in one go

Manually update the whitelist...

Exit Jenkins

Create/Update %USERPROFILE%.jenkins\scriptApproval.xml with the following content

<?xml version='1.0' encoding='UTF-8'?><scriptApproval plugin="script-security@1.23"><approvedScriptHashes></approvedScriptHashes><approvedSignatures><string>method hudson.model.Actionable getAction java.lang.Class</string><string>method hudson.model.Cause getShortDescription</string><string>method hudson.model.Run getCauses</string><string>method hudson.tasks.test.AbstractTestResultAction getFailCount</string><string>method hudson.tasks.test.AbstractTestResultAction getFailureDiffString</string><string>method hudson.tasks.test.AbstractTestResultAction getSkipCount</string><string>method hudson.tasks.test.AbstractTestResultAction getTotalCount</string><string>method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper getRawBuild</string></approvedSignatures><aclApprovedSignatures/><approvedClasspathEntries/><pendingScripts/><pendingSignatures/><pendingClasspathEntries/></scriptApproval>
  • Restart Jenkins
  • and then verify that the "In script approval" has the above entries approved
  • NOTE: Its the which is important. So if the scriptApproval file is already there, then you will generally need to ensure the contents of tag.


To expand upon @vikramsjn's answer, here is what I use to get the test summary in my Jenkinsfile:

import hudson.tasks.test.AbstractTestResultActionimport hudson.model.Actionable@NonCPSdef getTestSummary = { ->    def testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)    def summary = ""    if (testResultAction != null) {        def total = testResultAction.getTotalCount()        def failed = testResultAction.getFailCount()        def skipped = testResultAction.getSkipCount()        summary = "Test results:\n\t"        summary = summary + ("Passed: " + (total - failed - skipped))        summary = summary + (", Failed: " + failed)        summary = summary + (", Skipped: " + skipped)    } else {        summary = "No tests found"    }    return summary}

I then use this method to instantiate my testSummary variable:

def testSummary = getTestSummary()

This will return something similar to:

"Test results:     Passed: 123, Failed: 0, Skipped: 0"