If you look at the TearDown Script
of the project, it shows as below i.e., the variables already initialized by soapui.
Issue with your script
So if you look at it, there is runner
variable. Also the same variable is available at TearDown
script of test suite level. But, these are instances of different Objects. The script used in OP was of suite level which you aware and that is why you are not seeing in the result.
Here is the project level TearDown Script
and following in line comments.
/**
*
* Below is the TearDown script for SoapUI Project level
* Which create a custom report in a given file
* Modify the variable "reportFileName" below
*
**/
//Modify the file as needed for report file
//def reportFileName = '/tmp/abctestreport.txt'
//Adding the below as user wants specific directory
//Get the project path
def dataFolder = new com.eviware.soapui.support.GroovyUtils(context).projectPath
//Create today's date for storing response
def today = new Date().format("yyyy-MM-dd")
def filePrefix = "${dataFolder}/TestReports/xxx_WebAPI_${today}" as String
def fileNamePart = new Date().format("yyyy-MM-dd'T'HH.mm.ss")
//creating filename dynamically.
def reportFileName = "${filePrefix}/xxx_WebAPI_TestReport_${fileNamePart}.txt" as String
//NOTE: Not required to edit beyond this point
/**
* This class holds the test case details
**/
class TestCaseResultHolder {
def log
Map<String, String> properties = [:]
boolean status
def createProperties(testCase) {
testCase.getPropertyNames().each { key ->
properties[key] = testCase.getPropertyValue(key)
}
}
def getCaseResult(caseRunner, caseName) {
log.info "Checking test case status ${caseName}"
if ( caseRunner.status.toString() == 'FAILED' ){
log.error "Test case $caseName has failed"
for ( stepResult in caseRunner?.results ){
stepResult.messages.each() { msg -> log.info msg }
}
return false
} else {
log.info "${caseName} is passed"
}
true
}
def buildCaseResult(caseRunner, caseName) {
status = getCaseResult(caseRunner, caseName)
if (!status) {
createProperties(caseRunner.testCase)
}
}
}
/**
* This class holds the test suite details
**/
class SuiteResultsHolder {
def log
Map<String, TestCaseResultHolder> casaeResults = [:]
int testCaseCount = 0
int passedCasesCount = 0
int failedCasesCount = 0
def buildSuiteResults(suiteRunner, suiteName){
log.info "Building results of test suite ${suiteName}"
for ( caseRunner in suiteRunner?.results ) {
def caseName = caseRunner.testCase.name
testCaseCount++
def tcHolder = new TestCaseResultHolder(log: log)
tcHolder.buildCaseResult(caseRunner, caseName)
casaeResults[caseName] = tcHolder
if (tcHolder.status) {
passedCasesCount++
} else {
failedCasesCount++
}
}
}
def getStatus() {
(0 < failedCasesCount) ? false : true
}
}
/**
* This class holds the project details
**/
class ProjectResultsHolder {
def log
Map<String, SuiteResultsHolder> suiteResults = [:]
int suiteCount = 0
int passedSuitecount = 0
int failedSuiteCount = 0
def buildProjectResults(projectRunner, projectName) {
log.info "Building results of test project ${projectName}"
for(suiteRunner in projectRunner?.results) {
def suiteName = suiteRunner.testSuite.name
suiteCount++
def suiteResultsHolder = new SuiteResultsHolder(log: log)
suiteResultsHolder.buildSuiteResults(suiteRunner, suiteName)
suiteResults[suiteName] = suiteResultsHolder
if (suiteResultsHolder.status) {
passedSuitecount++
} else {
failedSuiteCount++
}
}
}
def getStatus() {
(0 < failedSuiteCount) ? false : true
}
}
//Get the status string based on boolean
def getResult(status){ status == true ? 'SUCCEED' : 'FAILED'}
//Draws a line
def drawLine(def letter = '=', def count = 70) { letter.multiply(count)}
//Gets the summary report
def getSummaryReport(project, projectResultHolder) {
def report = new StringBuffer()
report.append(drawLine()).append('
')
report.append("Test Execution Summary
")
report.append(drawLine('-', 60)).append('
')
report.append("Project : ${project.name}
")
report.append("Result : ${getResult(projectResultHolder.status)}
")
report.append("Total test suites executed: ${projectResultHolder.suiteCount}
")
report.append("Test suites passed: ${projectResultHolder.passedSuitecount}
")
report.append("Test suites failed: ${projectResultHolder.failedSuiteCount}
")
report.append(drawLine()).append('
')
report
}
//Gets the test case report
def getTestCaseReport(testCaseReport) {
def report = new StringBuffer()
report.append(drawLine('-', 60)).append('
')
report.append("Test Case Details:
")
report.append(drawLine('-', 60)).append('
')
testCaseReport.each { kase, tcReport ->
report.append("Name : ${kase}
")
report.append("Status : ${getResult(tcReport.status)}
")
if (!tcReport.status) {
report.append("Properties : ${tcReport.properties.toString()}
")
}
}
report
}
//Get the detailed report
def getDetailedReport(projectResultHolder) {
def report = new StringBuffer()
report.append(drawLine()).append('
')
report.append("Test Execution Detailed Report
")
report.append(drawLine()).append('
')
projectResultHolder.suiteResults.each { suite, details ->
report.append("Test Suite : ${suite}
")
report.append("Result : ${getResult(details.status)}
")
report.append("Total Cases : ${details.testCaseCount}
")
report.append("Cases Passed : ${details.passedCasesCount}
")
report.append("Cases Failed: ${details.failedCasesCount}
")
report.append(getTestCaseReport(details.casaeResults))
report.append(drawLine()).append('
')
report.append(drawLine()).append('
')
}
report
}
//Save the contents to a file
def saveToFile(file, content) {
if (!file.parentFile.exists()) {
file.parentFile.mkdirs()
log.info "Directory did not exist, created"
}
file.write(content)
assert file.exists(), "${file.name} not created"
}
def holder = new ProjectResultsHolder(log: log)
holder.buildProjectResults(runner, project.name)
def finalReport = new StringBuffer()
finalReport.append(getSummaryReport(project, holder))
finalReport.append(getDetailedReport(holder))
def reportFile = new File(reportFileName)
saveToFile(reportFile, finalReport.toString())
And here is the generated output:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…