Tuesday 13 December 2011

SoapUI Tip 3

It was a little searching using the javadocs of SoapUI, but if you want to log the result of the script of a mockService or mockResponse step in a testCase, then that can be done using:
log.info("Response: "+mockResponse.getMockResult().getResponseContent())
Another nice tip I found at another blog: "SoapUI limitations and workarounds : mock response test step"
If you want to use mockServices in your testcase or testsuite, but don't want to implement mockResponse steps for them, you can create (of course) mockServices for them. They can handle multple responses and use xpath expressions to choose the right response for a particular request. But running the testcase you'll need to start the mockServices that you need in the test. this can be done by in the "Setup Script" of the testCase:
def project = testCase.getTestSuite().getProject();
def mockService = project.getMockServiceByName("Name of the MockService");
mockService.start();
After running the testcase/testsuite the mockservices should be stopped neatly. This can be done in the "TearDown Script":
def project = testCase.getTestSuite().getProject();
def mockService = project.getMockServiceByName("Name of the MockService");
def mockRunner = mockService.getMockRunner();
mockRunner.stop();

Monday 12 December 2011

SoapUI: Properties from test Suite

In my previous post I showed how to get a file from a script in SoapUI. One of the parts on building the filepath of the file to load was a property from the mockService. The same thing is possible from a test suite. There are several places at which you can define properties. Amongst them is the TestSuite.

To get the properties from a test suite, you have to "get" it. To get the test suite on which you defined the properties goes as follows:

def project = mockResponse.mockOperation.mockService.project
def testSuite = project.testSuites["TestSupport"]

The property can then be fetched with:

def filePath = testSuite.getPropertyValue( "responseFilePath")


Test cases are part of the testSuite and they can be fetched from an string-based array in the same manner as getting the testSuite:

def testCase = project.testSuites["TestSuite 1"].testCases["TestCase 1"]

Expanding SoapUI possibilities...

Thursday 8 December 2011

Load Response Message File System in SoapUI

Today I figured out how to get a response from filesystem in SoapUI. I found that I could not dynamically select from multiple responses in a mockResponse-TestStep in a TestSuite. But loading from a file within a Groovy script should do the job. Advantage is also that you can have as many response files as you like. You just put a value in the filename, that you select using xpath from the request message. The folder in which you store the message can be put in a property on the mockService. I don't have the time to explain the whole lot. But the response in the mockService should be like:
<soapenv:envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:header>
      <darwinheader xmlns="http://www.darwin-it.nl/XMLHeader/10">
         <headerversion>${headerVersion}</headerversion>
         <messageid>${messageId}</messageid>
         <servicerequestordomain>${serviceRequestorDomain}</servicerequestordomain>
         <servicerequestorid>${serviceRequestorId}</servicerequestorid>
         <serviceproviderdomain>${serviceProviderDomain}</serviceproviderdomain>
         <serviceid>${serviceId}</serviceid>
         <serviceversion≶${serviceVersion}</serviceversion>
         <faultindication>${faultIndication}</faultindication>
         <messagetimestamp>${messageTimestamp}</messagetimestamp>
      </darwinheader>
   </soapenv:header>
   <soapenv:body>${responseBody}</soapenv:body>
</soapenv:envelope>
Here you see that the Soapenvelope with the header is given, but the diffent values are properties, as well as the responseBody. The script to get these from the request is as follows:
def method = "ChangeServiceRequest.Response 1.Script"
log.info("Start "+method)

log.info(mockRequest.requestContent)

def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
// Set Namespaces
def holder = groovyUtils.getXmlHolder(mockRequest.requestContent)
holder.namespaces["soapenv"] = "http://schemas.xmlsoap.org/soap/envelope/"
holder.namespaces["ns"] = "http://www.darwin-it.nl/XMLHeader/10"
holder.namespaces["rpy"] = "http://www.darwin-it.nl/ChangeServiceRequest/2/Rpy"


log.info("Get Header Properties")
context.messageId=Math.random()
log.info("messageId: "+context.messageId)
context.headerVersion= holder.getNodeValue("//ns:DarwinHeader/ns:HeaderVersion")
log.info("headerVersion: "+context.headerVersion)
context.serviceRequestorDomain= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceRequestorDomain")
log.info("ServiceRequestorDomain: "+context.serviceRequestorDomain)
context.serviceRequestorId= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceRequestorId")
log.info("serviceRequestorId: "+context.serviceRequestorId)
context.serviceProviderDomain= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceProviderDomain")
log.info("serviceProviderDomain: "+context.serviceProviderDomain)
context.serviceId= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceId")
log.info("serviceId: "+context.serviceId)
context.serviceVersion= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceVersion")
log.info("serviceVersion: "+context.serviceVersion)
context.faultIndication= holder.getNodeValue("//ns:DarwinHeader/ns:FaultIndication")
log.info("faultIndication: "+context.faultIndication)
context.messageTimestamp= holder.getNodeValue("//ns:DarwinHeader/ns:MessageTimestamp")
log.info("messageTimestamp: "+context.messageTimestamp)

def serviceRequestNr= holder.getNodeValue("//req:ChangeServiceRequest_Req/req:ServiceRequestData/req:ServiceRequestNumber")
log.info("ServiceRequestNr: "+serviceRequestNr)

def mockRunner = context.getMockRunner()
def mockService = mockRunner.mockService
def filePath = mockService.getPropertyValue( "responseFilePath")+"/FT01_ChangeServiceRequest_"+serviceRequestNr+".xml"
log.info("FileName: "+ filePath)
def File file = new File( filePath )
def fileLength = (int) file.length();
def buffer = new char[fileLength];
def inputReader = new FileReader(file);
def numChar = inputReader.read(buffer);
requestContext.responseBody = new String(buffer);
log.info("End "+method)
With "def holder = groovyUtils.getXmlHolder(mockRequest.requestContent)" you get an XML object of the request. The lines "holder.namespaces["ns"] = "http://www.darwin-it.nl/XMLHeader/10" set the namespace-abbreviations, needed to select the values from the request.
Then with "def serviceRequestNr= holder.getNodeValue("//req:ChangeServiceRequest_Req/req:ServiceRequestData/req:ServiceRequestNumber")", you can perform an xpath query, to get the serviceRequestNr from the request message in this case.

The lines
def mockRunner = context.getMockRunner()
def mockService = mockRunner.mockService
def filePath = mockService.getPropertyValue( "responseFilePath")

show how to read a property from the mockService.

Then the last lines are to determine the actual file path using this property and the  queried serviceRequestNr, and  to read the file.

By putting the file in the requestContext using: "requestContext.responseBody = new String(buffer);" it can be put in the response using the property "${responseBody}" like in the response-skeleton above. You might notice that it is a mixture of Java and Groovy. I'm not so familiar with Groovy yet. But I found that if it works in Java it is easy to get it work in Groovy. Actually, Groovy is just more loosely typed. I hope this clears enough to get this going. Good luck.