Sunday, January 24, 2016

Groovy for SoapUI - Diving into SoapUI automation concepts

SoapUI model items

ModelItems are the preliminary building blocks of a soapUI project. The elements such as projects, test suites, test cases, test steps, mock services, mock responses, and assertions are all implemented as ModelItems.
The com.eviware.soapui.model.ModelItem interface (http://www.soapui.org/apidocs/com/eviware/soapui/model/ModelItem.html) is the super interface which defines the general behavior of all soapUI model items. Does it sounds to be Greek and Latin! In Layman terms, all that you visualize and access in SoapUI Project are model items, which could then be accessible through scripts.
The SoapUI model items are commonly accessible through parent or children relationship.

HOW we track using LOGS?

Script Logs are used to show the log messages dumped by scripts invoked from various levels of the project.
There are two instances of script logs provided by SoapUI.

  • ·         Groovy Script TestStep includes a Log Output pane at the bottom of the editor which shows the log output if you run the Groovy Script individually.
  • ·         There is also a script log tab at the bottom of the log tool bar, which displays the log messages dumped by execution of Groovy Scripts from the TestCase and TestSuite levels of the SoapUI project. These two logs are shown in the following image.

Accessing LOG using script

  • Here comes the log object comes to scenario, that can be used in scripts at any level in a SoapUI project. Here is the different methods associated with log object,


Accessing SoapUI variables/ objects

The most used variables/ objects in SoapUI are
  • ·         log (object) – refer above
  • ·         messageExchange (variable)
  • ·         context (object)
  • ·         testRunner (variable)

messageExchange

SoapUI's MessageExchange interface defines methods for retrieving information related to test requests, including request and response data. 
Within a Groovy Script assertion, a built-in variable (messageExchange) provides access to an object of a class that implements the MessageExchange interface. Some of the common methods of the interface include,
  • ·         getEndpoint() : returns the target endpoint as a String
  • ·         getRequestContent() : returns the content of the test request
  • ·         getRequestContentAsXml() : returns the content of the test request (as XML)
  • ·         getResponseContent() : returns the content of the response to the test request
  • ·         getResponseContentAsXml() : returns the content of the response to the test request (as XML)
  • ·         getTimeStamp() : returns the request time stamp as a long number (see below for an example of converting from long to a standard time format)
  • ·         getTimeTaken() : returns the amount of time taken to process the request (in milliseconds)
  • ·         getRequestHeaders() : returns request headers as a StringToStringsMap object
  • ·         getResponseHeaders() : returns response headers as a StringToStringsMap object

Here is the link to complete list of methods supported by messageExchange variable - http://www.soapui.org/apidocs/com/eviware/soapui/model/iface/messageexchange.html


testRunner

The testRunner variables are used to execute tests in a SoapUI project. The sub interfaces of the com.eviware.soapui.model.testsuite.TestRunner interface (http://www.soapui.org/apidocs/com/eviware/soapui/model/testsuite/TestRunner.html) are used to execute various elements of a soapUI Project.
In this section, we will look into the usage of testRunner inside a SoapUI project. The testRunner interfaces provide methods such as start, cancel, and fail to control the test execution. Following are the commonly used methods of testRunner variable:
  • ·         cancel(String reason) : Cancels an ongoing test run with the specified reason
  • ·         fail(String reason) : Fails an ongoing test run with the specified reason
  • ·         getReason() : Gets the reason why a running test was canceled or failed
  • ·         getStartTime() : Returns the time this runner was last started
  • ·         getStatus() : Gets the current status of this TestRunner
  • ·         getTimeTaken() : Returns the time taken by this runner since its last start
  • ·         isRunning() : Lets the user know the current run status
  • ·         start(boolean async) : Starts running this TestRunners TestCase.
  • ·         waitUntilFinished() : Blocks until this runner is finished, (returns directly if it already has finished)



context

The context object holds information about a particular test run session. It can be used to read and write/update context-specific variables. There are different contexts available in a soapUI project, for example:
LoadTestRunContext : This holds context information about the loadtest run session
MockRunContext : This context is available for the duration of a Mock Services' execution
SubmitContext : This is available during one submit of a request
TestRunContext : This is available during a TestCase execution and all scripts in a TestCase run have access to the TestRunContext.
More information related to context object could be verified here - https://www.soapui.org/apidocs/com/eviware/soapui/model/testsuite/TestCaseRunContext.html

Following are the commonly used methods of context object (The associated methods vary based on the model item):
  • ·         getCurrentStepIndex() : Returns index of the current test step
  • ·         getProperty(String testStep, String propertyName) : Returns value of a property
  • ·         getTestCase() :  Fetches associated test case. Using this we can navigate through the model item hierarchy
  • ·         getTestRunner() : Call testRunner from context
  • ·         hasProperty() : Verifies for context related properties
  • ·         removeProperty() : Removes an existing context property
  • ·         setProperty() : Sets a context property
I I can understand that it might sound like Greek & Latin at start. But, when you start practicing it would be easy to handle. Please post comments if you got any suggestion/ feedback's.

13 comments:

  1. Hi Jayaraman,

    I am not able to fetch response using this getResponseContent() with messageExchange please help me how I can use this

    ReplyDelete
  2. Hi Sumi,

    Could you please run "messageExchange.hasResponseContent()" and confirm whether this script returns "true", because I need to ensure whether response is returned.

    Thanks,
    Kondasamy

    ReplyDelete
  3. Hi it still showing message "Mon Feb 27 17:24:54 IST 2017:ERROR:An error occurred: groovy.lang.MissingPropertyException: No such property: messageExchange for class: Script2

    Please help me
    "

    ReplyDelete
    Replies
    1. If my guess is correct, you are running this script from Groovy Script teststep, instead of running it within a script assertion.

      Delete
  4. Yes you are correct this is my code

    /*
    * ScriptName : CSVFile
    * Description : This script will create report file
    * PreRequisite : Create/Set Project level property "ProduceReports"
    * Author : Sumit Singh Gehlot (Willis Towers Watson)
    * Date : 09-Feb-2017
    */

    try {
    //Check a project level property to see if the reports should be produced.
    if(context.expand('${#Project#ProduceReports}') == 'true') {
    //The path and file to persist results
    def csvFilename = context.expand('${#Project#Outputpath}');//Report dynamic path set by this pickup from Project level property
    def resultDir = new File(csvFilename);//Above variable name used here
    if(!resultDir.exists())
    {
    resultDir.mkdirs();
    }
    def resultsFile = new File(resultDir, "QA_AviationExecutionReport.csv");

    //If the file does not already exist, we want to create it, otherwise we want to append
    if(!resultsFile.exists())
    {
    resultsFile.createNewFile();
    //Header values
    resultsFile.write('"TEST CASE TITLE","RESULT","MESSAGES","DATE"');
    }

    //Write the result values
    resultsFile.append('\n'); //Newline
    resultsFile.append('"' + testRunner.testCase.name + '",'); //Test Case Name
    resultsFile.append('"' + testRunner.status + '",');


    //Overall Test Case result
    //There can be multiple messages, so set up a loop
    resultsFile.append('"'); //Start of messages.
    for(result in testRunner.getResults()) {

    //There can be lots of messages, so limit amount recorded to avoid going over
    //the buffer size for a CSV field
    msgCount = 0;
    for(message in result.getMessages()) {
    msgCount++;
    if(msgCount < 10) {
    resultsFile.append(message + ';\n');

    }
    }
    }

    resultsFile.append('",'); //End of messages.
    //resultsFile.append('"' + testRunner.getReason() + '",');//This is not for response capturing but for response caturing step should be only added here
    resultsFile.append('"' + messageExchange.hasResponseContent() + '",');
    //resultsFile.append('"' + result.getResponseContent() + '",');


    def currentDate = new Date().format("yyyy-MM-dd hh:mm");
    resultsFile.append('"' + currentDate + '"');
    }
    } catch(e) {
    log.error("An error occurred: " + e.toString());
    }

    ReplyDelete
  5. In this case, you can't use messageExchange variable directly. You should use testRunner variable to get the response contents as below,

    testRunner.testCase.getTestStepByName("MY_TESTCASE_NAME").getHttpRequest().getResponseContent()

    ReplyDelete
  6. I am using this above code for generating CSV Execution report & I also want to add Response column to this report, please suggest me how I append Response column to my Report. or If you have some other framework so please share with me that will be great help for me

    ReplyDelete
  7. I have already given the solution in my previous comment. Additionally, if you want a SoapUI plugin to do this job, I have one here,

    https://github.com/Kondasamy/soapui-readyapi-test-execution-excel-report

    ReplyDelete
  8. Hi Kondasamy,

    I need your help... in my web service header take parameter as a cookie..do you have any regarding cookie how to handel cookie in parameters

    Regards,
    Sumit Singh Gehlot

    ReplyDelete
  9. Hello Kondasamy,

    After reading your article which is great to learn how code inside soapUi works, I am still wondering how testRunner interface works.

    My question is the following :
    How could I use testRunner object in these differents context :
    1) Inside Setup Script of Project level
    2) Inside Setup Script of TestSuite level
    3) Inside Setup Script of TestCase level
    4) Inside TestStep groovy script

    For the moment, I can only use testRunner class inside a groovy script teststep. I do not understand how could I use this object in another context.

    Regards,

    ReplyDelete
    Replies
    1. Hi SaverHold,

      Great to see your feedback. Regarding your question, you can take a look at the SoapUI javadoc - https://www.soapui.org/apidocs/com/eviware/soapui/model/testsuite/TestRunner.html

      1) At project level - you will find either 'load script' and 'save script', where you can use project variable (which is an instance of com.eviware.soapui.impl.wsdl.WsdlProject). Remember it is not equivalent to testRunner.
      2) At testsuite level - you will find 'setup script' and 'teardown script', where you can use runner variable. This is equivalent to testRunner, but it is an instance of com.eviware.soapui.impl.wsdl.panels.support.MockTestSuiteRunner
      3) At testcase level - you will also find 'setup script' and 'teardown script', where you can use testRunner variable which is an instance of com.eviware.soapui.impl.wsdl.panels.support.MockTestRunner

      All together they runs all steps in a TestCase or a SecurityTest and collects performance data.

      Thanks,
      Kondasamy

      Delete
  10. I'm using script assertion and unable to get response, pops out saying message exchaNge for class error. i get output both in XML and json . i need to get node value . can you please help me regarding same. i use soap 4.5.1

    ReplyDelete
  11. Hello!

    I'm not clear about the question here; will be clear if you could attach sample response and scripts. But, I'll try to help with some possible solution now.

    We could consider the XML snippet in the below link as the response XML and the highlighted part of tag as the tag need to be validated.

    https://gist.github.com/Kondasamy/1bcc7bd8af2c2b60c2de44d5abfe9848

    Create a groovy script assertion and use the code below to get the value of XML node,

    //Get the response XML of the targeted teststep and store it in a temporary variable
    def records=new XmlParser().parseText(messageExchange.getResponseContent())
    //In the below line of code 'f:length' is the tag need to be validated
    assert records.'**'.'f:length'.text()!= null


    Hope this helps.

    ReplyDelete

Leave out your valuable feedback's here!!!!!!