0

I tried to change the code that @Rao wrote, here's a link! to show the details of the Test Steps in the report, unfortunately it does not work. Could someone help?

My question is really on syntax, I want to develop a report when the whole project is run, it outputs the following results:

  • Project Name - is it success or failed. If one suite failed then project fails else it passes
  • Test Suite - Take name of each test suite in project and if passes then place 'Succeed' next to name of test suite else place 'Failed' next to name of test suite
  • Name of all test cases within test suite. Like the one in screenshot really, 'succeed' next to test cases that have passed and 'failed' next to those that haven't.
  • Test Step- Take name of each test step in project and if passes then place 'Succeed' next to name of test step else place 'Failed' next to name of test step
  • Finally the property values. If a test case has failed, capture the property values for that failed test case so we can track which values were entered that caused the failure of the test

Below is the code:

/**
*
* 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/Local_AllModules_Report_${today}" as String

def fileNamePart = new Date().format("yyyy-MM-dd'T'HH.mm.ss")

//creating filename dynamically.
def reportFileName = "${filePrefix}/Local_AllModules_TestReport_${fileNamePart}.txt" as String


//NOTE: Not required to edit beyond this point

/**
* This class holds the test step details
**/
class TestStepResultHolder {
    def log
    Map<String, String> propertiesTest = [:]
    boolean status

    def getTestStepList(testCase) {
        testCase.getTestCase().each { key ->
            propertiesTest[key] = testCase.getTestStepByName(key)
        }       
    }

    def getStepResult(stepRunner, stepName) {
        log.info "Checking test case status ${stepName}"
        if ( stepRunner.status.toString() == 'FAILED' ){
            log.error "Test case $stepName has failed"
            for ( step_Result in stepRunner?.results ){
                step_Result.messages.each() { msg -> log.info msg }
            }
            return false
        } else {
            log.info "${stepName} is passed"
        }
        true
    }

    def buildStepResult(stepRunner, stepName) {
        status = getStepResult(stepRunner, stepName)
        if (!status) {
            createProperties(stepRunner.testCase)
        }
    }

}

/**
* 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('\n')
    report.append("\t\t\tTest Execution Summary\n")
    report.append(drawLine('-', 60)).append('\n')
    report.append("Project : ${project.name}\n")
    report.append("Result : ${getResult(projectResultHolder.status)}\n")
    report.append("Total test suites executed: ${projectResultHolder.suiteCount}\n")
    report.append("Test suites passed: ${projectResultHolder.passedSuitecount}\n")
    report.append("Test suites failed: ${projectResultHolder.failedSuiteCount}\n")
    report.append(drawLine()).append('\n')
    report
}

//Gets the test case report
def getTestCaseReport(testCaseReport) {
    def report = new StringBuffer()
    report.append(drawLine('-', 60)).append('\n')
    report.append("\t\tTest Case Details:\n")
    report.append(drawLine('-', 60)).append('\n')
    testCaseReport.each { kase, tcReport ->
        report.append("Name : ${kase}\n")
        report.append("Status : ${getResult(tcReport.status)}\n")
        if (!tcReport.status) {
            report.append("Properties : ${tcReport.properties.toString()}\n")
        }
    }
    report
}

//Gets the test step report
def getTestStepReport(testStepReport) {
    def report = new StringBuffer()
    report.append(drawLine('-', 60)).append('\n')
    report.append("\t\tTest Case Details:\n")
    report.append(drawLine('-', 60)).append('\n')
    testStepReport.each { kaset, tsReport ->
        report.append("Name : ${kaset}\n")
        report.append("Status : ${getResult(tsReport.status)}\n")
        if (!tsReport.status) {
            report.append("Properties : ${tsReport.propertiesTest.toString()}\n")
        }
    }
    report
}

//Get the detailed report
def getDetailedReport(projectResultHolder) {
    def report = new StringBuffer()
    report.append(drawLine()).append('\n')
    report.append("\t\t\tTest Execution Detailed Report\n")
    report.append(drawLine()).append('\n')
    projectResultHolder.suiteResults.each { suite, details ->
        report.append("Test Suite : ${suite}\n")
        report.append("Result : ${getResult(details.status)}\n")
        report.append("Total Cases : ${details.testCaseCount}\n")
        report.append("Cases Passed : ${details.passedCasesCount}\n")
        report.append("Cases Failed: ${details.failedCasesCount}\n")
        report.append(getTestCaseReport(details.casaeResults))
        report.append(drawLine()).append('\n')
        report.append(drawLine()).append('\n')
    }
    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())
Martin Evans
  • 45,791
  • 17
  • 81
  • 97
k.rak
  • 1
  • 2
  • Welcome to Stack Overflow! When posting code, you should follow [these guidelines](https://stackoverflow.com/help/mcve) to help you get better answers. You should also avoid simply asking if someone can help. Rather, share the error you receive and fixes you have already tried. – ScoobyDrew18 Nov 15 '17 at 20:50
  • What you are seeking is already there just below the project or suite with key `RESULT`. Not sure what more you wanted to customize. Hope you saw the sample report which was available in the original post's answer. – Rao Nov 16 '17 at 00:31
  • I would like my report to contain even more details about TestSteps, your report only contains information about TestCase, and I need to know which step did not pass. – k.rak Nov 18 '17 at 00:40

1 Answers1

0

To get test step result you may add a script like the one I use in your testcase's teardown script:

log.info "nb steps : " + testRunner.getTestCase().getTestStepCount()

for (testStep in testRunner.getResults()){
  log.info "step " + testStep.getTestStep().getName() + " : " + testStep.getStatus()
}

You can also add the following in the testsuite's teardown script but when you run at testsuite level you will not get testcase's teardown scripts:

log.info "*********** EXECUTION SUMMARY *****************************************"
def runner = context.testRunner;


//log.info "nb test results = " + runner.getResultCount()

for (testRun in runner.getResults())
{
    testCase = testRun.getTestCase()

    //log.info "testCase " + testCase
    log.info context.expand( '${#Project#testcase_flag}' ) + testCase.getName()
    log.info "nb test steps = "+ testCase.getTestStepCount()

    for (testResult in  testRun.getResults())
        log.info testResult.getTestStep().getName() + " : " + testResult.getStatus()

    log.info context.expand( '${#Project#testcase_status_flag}' ) + " : " + runner.getStatus()
}
log.info "*************************************************************************************"

This works pretty well for me ...

A.Joly
  • 2,317
  • 2
  • 20
  • 25