XPATH Dispatch in SoapUI Mock service/ Mock operation - xpath

I am new in SoapUI, and was trying to understand the use of XPATH dispatch for a mock operation in a mock service.
Here is what I have done so far
Created a mock service for a calculator
Added mock operation substract
Following is a sample request for the operation
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.parasoft.com/wsdl/calculator/">
<soapenv:Header/>
<soapenv:Body>
<cal:subtract>
<cal:x>1</cal:x>
<cal:y>1</cal:y>
</cal:subtract>
</soapenv:Body>
</soapenv:Envelope>
Following is a sample response for the same
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.parasoft.com/wsdl/calculator/">
<soapenv:Header/>
<soapenv:Body>
<cal:subtractResponse>
<cal:Result>?</cal:Result>
</cal:subtractResponse>
</soapenv:Body>
</soapenv:Envelope>
I was able to understand about other dispatch but not about XPATH as following is what I have entered in the XPATH dispatch
declare namespace cal='http://www.parasoft.com/wsdl/calculator/';
declare namespace soapenv='http://schemas.xmlsoap.org/soap/envelope/';
//cal:subtract/cal:x
It was also observed that if I have already used SCRIPT dispatch and switch to XPATH from the dropdown, the script is visible in the declaration/scripting box/area
Following are the questions:
Is XPATH and SCRIPT dispatch same
If not, how does the XPATH dispatch actually work to identify what response to dispatch out of all form MockResponses list
Kindly help me with this.
PS: I have already gone through
http://www.soapui.org/soap-mocking/reference/mockoperation.html
http://www.soapui.org/soap-mocking/mockoperations-and-responses.html

The soapUI documentation that you mentioned in your question is the right location to get the information. However, the information available is not complete.
After searching for sometime, found the details.
Initially, got confused between Xpath and Script Dispatch methods.
Here is the additional information than what you are looking for:
Is XPATH and SCRIPT dispatch same
Answer is NO. Both are different
If not, how does the XPATH dispatch actually work to identify what response to dispatch out of all form MockResponses list
The following information found in the documentation:
XQUERY - This is similar to the QUERY_MATCH but not quite as powerful; an XPath expression is applied to the incoming request and the resulting value is used for selecting which MockResponse to be returned. In our previous example of search results, we could set the XPath expression to select a search term and then create MockResponses named after each expected value. The advantage being that we don’t need to add new XPath statements for new search criteria, just another MockResponse.
Assume that you created multiple responses say PositiveResponse, NegativeResponse, ZeroResponse for subtract operation of Mock Service.
Here are the sample conditions that you may want to apply on the request and dispatch appropriate response. Of course, you may have as many as you require.
PositiveResponse - if x, y values are 10, 5 respectively.
NegativeResponse - if x, y values are 5, 10 respectively.
ZeroResponse - otherwise (this is mandatory if none of the above satisfy).
Here is how you need to write in the editor given for XPATH Dispatch mode
declare namespace cal='http://www.parasoft.com/wsdl/calculator/';
if (//cal:subtract/cal:x[. = '10'] and //cal:subtract/cal:y[. = '5']) then
'PositiveResponse'
else
if (//cal:subtract/cal:x[. = '5'] and //cal:subtract/cal:y[. = '10']) then
'NegativeResponse'
else
'ZeroResponse'
Hope you are now aware and differentiate the SCRIPT Dispatch mode.
I think the confusion created because both SCRIPT and XPATH shows an editor of same type. But the content inside of it will be entirely different. Also you can easily see a message on top of the editor that log, context, mockRequest availability of variables if you select SCRIPT Dispatch mode and it vanishes when XPATH is choosen.
Just giving SCIRPT example in case if you are interested in it:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def holder = groovyUtils.getXmlHolder(mockRequest.requestContent)
def x = holder.getNodeValue("//*:x") as int
def y = holder.getNodeValue("//*:y") as int
context.result = x - y
A simple test can be (to differentiate between the two), copy the above script for xpath and try testing and soap fault is received saying does not know groovyUtils. This test will confirm that xpath and script are different.
Here you may not needed to create multiple responses as the above code can handle dynamic input values and set the result in the response.
MockReponse for subtract operation may look like below with place holder as ${result}.
MOCKRESPONSE for SCRIPT:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.parasoft.com/wsdl/calculator/">
<soapenv:Header/>
<soapenv:Body>
<cal:subtractResponse>
<cal:Result>${result}</cal:Result>
</cal:subtractResponse>
</soapenv:Body>
</soapenv:Envelope>
Hope this clarifies.

Related

How to Extract parent value on the basis of Child Json parameters where multiple child units are present

I have to extract multiple correlating variables from a response (which is json) in JMeter. Part of the response is listed below:
I have tried $..[?(#.sType == '7')].tId but its not worked for me
To proceed with the next request, I have to extract tId (2309), on the basis of " Stype = 7 " There are several units, each unit has several children and each children has several contents. Each content id matches just one children id and each children id matches just one unit id. Ids have to be selected on a random basis.
I've tried to extract all ids from the response and use them randomly, but it doesn't work this way.
Posting incomplete JSON is some form of disregard to the community, you're supposed to create a minimal reproducible example yourself, I'll note your username and it will be the last time you're having support from me.
Coming back to your question:
Try something like:
topics.*[?(#.tSections[3].sType == 7)].tId
Demo:
More information:
JsonPath Filter Operators
API Testing With JMeter and the JSON Extractor
You cannot get parent of a JSON node using JSON Extractor. you will need to write custom code in groovy / javascript with for-loops

How can i get this value with XPATH in JMeter

I have a webservice response as such :
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<FileResponse xmlns="http://xxx.x.sx.be">
<id>090150e080249d09</id>
</FileResponse>
</soap:Body>
</soap:Envelope>
I am trying to extract the value of "id" but i can't seem to figure out the right query. I used an online generator which provided :
/soap:Envelope[#xmlns:soap="http://www.w3.org/2003/05/soap-envelope"]/soap:Body/FileResponse[#xmlns="http://xxx.x.sx.be"]/id/text()
But it doesn't seem to work in Jmeter as the response is always null.
I found this to be the answer : //*[local-name() = 'id']
Your test for the namespace is invalid. Xpath queries do not support this.
Instead you will need to JMeter to pass in the namespaces declarations along with the xpath query. I dont know how JMeter does that but I can give you an xpath expression that may work around it.
//*[local-name()='FileResponse']/*[local-name()="id"]/text()
The xpath will test the name of the node and ignoring the namespaces. Its not recomended practice to test without namespaces and could be slow but it'll work.

Conditionally Save responses to a file based on HTTP code or body string

I'm a newbie in using Jmeter and searching for a solution solving the following problem: I have a suite that contains a set of atomic HTTP requests and the goal is to save response bodies into an xml file. Currently, I'm handling that with using "Save Responses to a file listener", but need to be able to save separately error and OK responses in different XML, based on response HTTP code and body string.
to illustrate the case with dummy code
if (HTTP response code == 200 OK && body does not contain "ERROR") then
save response to file (%path%\responsename_OK.xml
else
save response to file (%path%\responsename_ERROR.xml
My bad, Nikolay, I forgot you wanted it in xml format...
Well, the easiest way is to add 2 Simple Data Writers (SDW) to each HTTP Request where 1 SDW logs only errors and the other logs only successes.
The Pro's are
it's easy and once you set it up for 1 HTTP Request, you can simply copy it to every other HTTP Request
Each success or failure with be appended to the corresponding .xml file
You can define as much or as little detail as you want
The Con is you add 2 elements to each Request, thus increasing your test size twice as much as you would with a BeanShell Assertion. (if that's a concern for you.)
If you want a more detailed way, you could try a BeanShell Assertion scripted with XML Parsers and XPath Assertions like outlined here.
Use Response Assertion (in fact you will need 2: one for Response Code and another one for Response Body checking) in order to fail the request basing on these criteria
Use If Controller for setting a condition:
${JMeterThread.last_sample_ok} will be triggered if previous sampler is successful
!${JMeterThread.last_sample_ok} - will fire if previous sampler fails
N.B. you should have any Sampler under the If Controller so it could work.

How to extract a response value when doing http post using Jmeter

Can anyone please help me here? I'm trying to do an http post in Jmeter, http works fine, but I'd like to extract the LastName value from the response to use in next http request. I've tried several methods using Xpath Extractor but the Debug sampler shows nothing. I've added XPath_Extractor as a child of HTTP Sampler.
what am I doing wrong here?
Here is what I setup in the XPath Extractor
Reference Name = lstname (which is the variable I carry to next http request)
XPath Query = //*[local-name()='LastName']/text()
also tried
/Reply/CustomerData/#LastName
Main Sample checked
Use NameSpaces- checked
Ingnore whitepspaces checked
Here is my http response
<?xml version="1.0" encoding="UTF-8"?>
<dm:reply xmlns:dm="http://www.xx.com/dm" version="1.0">
<Session>
<TimeDate CurrentDateTime="2015-12-16T08:57:21" CurrentMilliseconds="2881062362"/>
<Reply type="Connection">
<ErrorMessage/>
<ErrorCode>0</ErrorCode>
</Reply>
<TimeDate CurrentDateTime="2015-12-16T08:57:21" CurrentMilliseconds="2881062504"/>
<Reply type="Execute">
<CustomerData FirstName="" LastName="Moni" Address="SD" Chassis="AWD" CountryOfBirth="" CountryOfOriginFullName= Year="2010">
<RecordSet>
</RecordSet>
<ErrorMessage/>
<ErrorCode>0</ErrorCode>
</CustomerData>
</Reply>
<TimeDate CurrentDateTime="2015-12-16T08:57:21" CurrentMilliseconds="2881062590"/>
</Session>
</dm:reply>
You can use regular expression extractor - Post Processor to achieve this.
You need to fill in following parameters
Reference Name: LastName
The regular expression (would look like): LastName="(.*?)"
Template: $1$
Match : 1
Default Value: NotFound
Use ${LastName} in next request to access extracted value of LastName.
Add debug sampler to check if you are extracting correct value.
Why do you need all this namespaces stuff?
Don't check any boxes in the extractor
Use //CustomerData/#LastName as XPath expression
That's it
By the way, you can evaluate XPath Expressions directly against response using XPath Tester mode of the View Results Tree listener. See How to debug your Apache JMeter script article for more tips on getting to the bottom of your JMeter test issue.

How to generate the following XML using Savon

I have been trying to know how to build a SOAP XML request having different tags with different namespaces through Savon - as that shown below - but haven't been able to do it yet. Could anybody please help me? The request written below was generated by SOAPUI (linked it a WSDL). Notice the urn and urn1 prefixes for namespaces. I use Savon 2, Ruby 1.9 and Rails 3.
<soapenv:Envelope xmlns:urn="urn:safetypay:messages:mws:api" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn1="urn:safetypay:schema:mws:api">
<soapenv:Body>
<urn:ExpressTokenRequest>
<urn1:Language>ES</urn1:Language>
<urn:Signature>2984764ac8214cca0a44e06badaba4bbc93ed381af59199f65d9c</urn:Signature>
</urn:ExpressTokenRequest>
</soapenv:Body>
</soapenv:Envelope>
Thank you in advance :)
I WANT TO SHARE THE SOLUTION:
Finally, I was able to puzzle it out. Notice that the code posted in this forum is not exactly the real one for security and/or brevity purposes (it's incomplete).
# Instance of the Savon client using the respective wsdl. Notice the two (multiple) namespaces.
# Also, see the namespace prefix urn (making it different to the default one).
# In addition,the code changed the envelope namespace prefix to soapenv.
# While debugging in console (irb), I used the parameters log: true, pretty_print_xml: true inside the following client instance too (e.g. ...env_namespace: :soapenv, log: true, pretty_print_xml: true... ). This allowed me to see very easily the XML Savon was sending when requesting.
# Remember to require the necessary resources. Maybe require 'savon', require 'digest',...
client = Savon.client(wsdl: "/MerchantExpressWs.wsdl", namespaces: {"xmlns:urn" => "urn:safetypay:messages:mws:api", "xmlns:urn1" =>"urn:safetypay:schema:mws:api"}, namespace_identifier: :urn, env_namespace: :soapenv)
# Assignment of variables below must be done in this case. I don't write it here to be this code not so large.
# A thing I lasted much time to know how to do was to add the prefix urn1 only to the tag Language (urn1:Language), since the code was adding urn to all due to the namespace_identifier: :urn (see the client instance above). As you can see, I simply added it to the array message (message1).
message1 = {"urn1:Language" => language, "Signature"=> signature }
# The respective operation for this request is create_express_token.
response = client.call(:create_express_token, message: message1 )
# This was the way Savon sent the request as needed by the Web Service. Savon added additional namespaces in comparison to the original XML request I wanted to send, but it was not problematic, it was OK (e.g., it added some additional stuff to the namespaces soapenv, urn, urn1)
I hope this post helps many to make easy to consume SOAP Web Services through Savon - Ruby (and maybe with Rails).
Thank God primarily for every good thing :)

Resources