in jenkins-pipeline-shared-libraries/vars/util.groovy [262:318]
def retrieveFailedTests(String buildUrl = "${BUILD_URL}") {
def testResults = retrieveTestResults(buildUrl)
def allCases = []
testResults.suites?.each { testSuite ->
allCases.addAll(testSuite.cases)
}
def failedTests = []
testResults.suites?.each { testSuite ->
testSuite.cases?.each { testCase ->
if (!['PASSED', 'SKIPPED', 'FIXED'].contains(testCase.status)) {
def failedTest = [:]
boolean hasSameNameCases = allCases.findAll { it.name == testCase.name && it.className == testCase.className }.size() > 1
failedTest.status = testCase.status
// Retrieve class name
fullClassName = testCase.className
int lastIndexOf = fullClassName.lastIndexOf('.')
packageName = fullClassName.substring(0, lastIndexOf)
className = fullClassName.substring(lastIndexOf + 1)
failedTest.name = testCase.name
failedTest.packageName = packageName
failedTest.className = className
failedTest.enclosingBlockNames = testSuite.enclosingBlockNames?.reverse()?.join(' / ')
failedTest.fullName = "${packageName}.${className}.${failedTest.name}"
// If other cases have the same className / name, Jenkins uses the enclosingBlockNames for the URL distinction
if (hasSameNameCases && testSuite.enclosingBlockNames) {
failedTest.fullName = "${testSuite.enclosingBlockNames.reverse().join(' / ')} / ${failedTest.fullName}"
}
// Construct test url
String urlLeaf = ''
// If other cases have the same className / name, Jenkins uses the enclosingBlockNames for the URL distinction
if (hasSameNameCases && testSuite.enclosingBlockNames) {
urlLeaf += testSuite.enclosingBlockNames.reverse().join('___')
}
urlLeaf += urlLeaf ? '___' : urlLeaf
urlLeaf += "${failedTest.name == "(?)" ? "___" : failedTest.name}/"
urlLeaf = urlLeaf.replaceAll(' ', '_')
.replaceAll('&', '_')
.replaceAll('-', '_')
failedTest.url = "${buildUrl}testReport/${packageName}/${className}/${urlLeaf}"
failedTest.details = [null, 'null'].contains(testCase.errorDetails) ? '' : testCase.errorDetails
failedTest.stacktrace = [null, 'null'].contains(testCase.errorStackTrace) ? '' : testCase.errorStackTrace
failedTests.add(failedTest)
}
}
}
return failedTests
}