Forum Discussion

Itam_Media's avatar
Itam_Media
Contributor
14 years ago

Issue with Customizing JUnit Reports when using Excel Dataso

I am running a testcase which loads data from an excel sheet and runs through them (using the DataSource Loop step). When we run this using maven, we want the Junit reports generated to not just say whether the testcase passed or failed, but actually give us the row information (from the excel spreadsheet) that passed or failed (also print the data and assertion from that row in excel ).

To achieve this, I wrote a custom JUnitReportCollector (and override the afterStep method)

public class ICJUnitReportCollector extends JUnitReportCollector
{

public void afterStep(TestCaseRunner testRunner, TestCaseRunContext runContext, TestStepResult result)
{
TestStep currentStep = result.getTestStep();
WsdlDataSourceTestStep wsdlDataSourceTestStep = null;
if (currentStep instanceof WsdlDataSourceTestStep){
wsdlDataSourceTestStep = (WsdlDataSourceTestStep) currentStep;
_currentRow = wsdlDataSourceTestStep.getCurrentRow();
SoapUI.log.info("Debug: wsdlDataSourceTestStep - current row " + _currentRow);
Map wsdlDataSourceTestStepProperties = wsdlDataSourceTestStep.getProperties();
Iterator iter = wsdlDataSourceTestStepProperties.entrySet().iterator();
while (iter.hasNext()){
Map.Entry entry = (Map.Entry) iter.next();
SoapUI.log.info("Debug: wsdlDataSourceTestStep - property name " + entry.getKey() + " with value " + ((TestStepProperty)entry.getValue()).getValue() );
}
}
\\\
}
}


My issue is this:
i) The afterStep gets called only once even though there are multiple rows of data in the excel spreadsheet. I would expect this to be called for every row of data. Is my understanding correct? Is there some other way I can do the acheive the same thing.

ii) To even get this far, I had to set the reportcollector (on my custom extension to SoapUIProTestCaseRunner) using reflection (because the reportcollector is a private field on SoapUIProTestCaseRunner ). Do you provide extension points for us to do this directly from the API.

Please contact me for any questions/information.

-- Sang

4 Replies

  • SmartBear_Suppo's avatar
    SmartBear_Suppo
    SmartBear Alumni (Retired)
    Hi Sang,

    ok, I've moved the creation of the reportcollector to a protected factory method that you can override in your derived class, ie add

    protected JUnitReportCollector createJUnitReportCollector()
    {
    return new ICJUnitReportCollector ();
    }

    will be in upcoming nightly build. Regarding the afterStep handler this is odd, can you apply the above and get back to me if you still have that issue?

    regards!

    /Ole
    eviware.com
  • I don't think your fix will work correctly because you have this in the SoapUITestCaseRunner class

     public void setJUnitReport(boolean junitReport)
    {
    this.junitReport = junitReport;
    if(junitReport)
    reportCollector = new JUnitReportCollector();
    }


    So
    i) When the setJUnitReport(true) gets called, the reportCollector will become the default one which is not the behavior we want
    ii) Once i) is taken care of, can you also make sure that the same custom reportCollector gets used all through the execution. Currently I have a feeling that it is only using the custom reportCollector for the first row of data and then going back to the default JUnitReportCollector (this is my guess based on the behavior that I am seeing).

    Would apprecatiate your comments/fixes for my concerns above.

    Thanks
    -- Sang
  • jkester's avatar
    jkester
    Occasional Contributor
    You can find the existing report collector by just asking any existing testcase.
    You can then attach the same report collector to any new testcase you generate.


    Some example code I just tried out on 4.5:

    (1..5).each {
    //log.info it
    def templateTc = testRunner.testCase.testSuite.testCases["tc1"]
    def listenerList = testRunner.testCase.getTestRunListeners();
    def junitReportCollector = listenerList.find {
    it.class.name =~ 'JUnit'
    }
    log.info "JunitReportCollector = $junitReportCollector"
    def newName = "newtc$it"
    def tc = testRunner.testCase.testSuite.cloneTestCase(templateTc,newName)
    if (junitReportCollector != null) {
    tc.addTestRunListener(junitReportCollector);
    }
    log.info "Executing new testcase ${tc.name}"
    sleep(2000)
    def runner = tc.run(new com.eviware.soapui.support.types.StringToObjectMap(), false)
    testRunner.testCase.testSuite.removeTestCase(tc);
    }



    I want to apply this on a datasource too: loop through the records, and for every record clone a test case with a meaningful name, register it to junit report, execute it, remove it.
    I think/hope it will work ...


    Regards, Jan.
  • SmartBear_Suppo's avatar
    SmartBear_Suppo
    SmartBear Alumni (Retired)
    Hi Sang!

    Do you consider this issue as resolved?


    --
    Regards

    Erik
    SmartBear Sweden