I have been using soapUI Pro for testing web services for a while now. soapUI is a neat tool for web services testing. However, it lacks fair amount of documentation. During my hands-on time with soapUI I learnt a lot of tricks and tips that I think I can share with you in order to save you some frustration that I went through.
In this post, I shall go over how to insert an xml node in soapUI property transfer step. Property transfer is a test step that allows you to transfer data from one xml request or response to another. For example, say you execute a request to search for a book and the response of this request is a number of xml book nodes. The next request you want to issue is to buy a book. In next request you need one of the book nodes obtained in the response of previous request. Following flow of events can help understand this scenario.
-> Issue a “searchBook” request for a book
-> results in a “searchBookResults” of xml book nodes
-> select one of these nodes and submit it in “buyBook” Request
In the scenario above you can use soapUI’s property transfer step to transfer an xml “Book” node from “searchBookResults” to “buyBook” request. For transferring basic node data like text() or attribute values you can refer to soapUI’s documentation at
http://www.soapui.org/userguide/functional/propertytransfers.html
Assuming you are familiar with basic soapUI Property Transfer, Iet’s try to understand how exactly we can achieve a node transfer of the kind listed above with example xml requests:
[Note: for the sake of simplicity I am not using namespaces in this example]
Sample Book Search Request:
<searchBook> <searchName>Design Patterns</searchName> </searchBook>
Sample Book Search Results:
<searchBookResults> <book> <id>1234</id> <name>Design Patterns</name> <author>John Doe</author> <desc>A good book on design patterns</desc> <paymentDetails> <totalPrice>30.00</totalPrice> </paymentDetails> </book> ... ... ... </searchBookResults>
Sample Buy Book Request to be created:
<buyBook> <book> <id>1234</id> <name>Design Patterns</name> <author>John Doe</author> <desc>A good book on design patterns</desc> <paymentDetails> <totalPrice>30.00</totalPrice> <!-- Optional Element that needs to be inserted only at the buy SOAP Requst --> <frequentBuyerCard>BN-987654321</frequentBuyerCard> </paymentDetails> </book> </buyBook>
Case I
Now let’ see a simple property transfer that transfers the entire book node with id=1234:
Property Transfer Source Window Code Looks like:
//bookSearchResults/book[id/text()='1234'][1]
If you notice above ‘id/text()=’1234′ sets the selection criteria and [1] selects the first node in an array of nodes matching the criteria. Also do not forget to check option “Transfer Child Nodes” in your property transfer. This makes sure that entire tree below the node being transferred is transferred to the target.
Property Transfer Target Window Code Looks like:
//buyBook[1]/book[1]
Its important that your target SOAP Request has an empty ‘book’ node under the ‘buyBook’ node. Unless your target request has a node, property transfer shall not be able to transfer anything from source to target. For example, in case below if you did not have empty ‘book’ node, property transfer would complain that book[1] node is missing!
Case II
Now the real deal ! What if you want to insert that optional node shown in buyBook Request above? This optional node is buyer’s frequent buyer card number that needs to be submitted along with buyBook request so that appropriate club points are deposited to this card number as a result of this transaction.
Here is how=>
First you would have to transfer the node as shown above in a property transfer, say, “TransferBook”. So typically your test case shall have following steps in that order:
1. SearchBook – SOAP Test Request Step
2. TransferBook – Property Transfer Step (Its source is Search Results and target is buyBook Request)
3. BuyBook – SOAP Test Request Step
Now you shall create a new Property Transfer Step, say, “InsertCard” and your sequence of steps shall now look like:
1. SearchBook – SOAP Test Request Step
2. TransferBook – Property Transfer Step ( At end of this step we would have simple buyBook request )
3. InsertCard – Property Transfer Step ( At end of this step we would have inserted card node in buyBook request )
4. BuyBook – SOAP Test Request Step
[note: InsertCard property transfer step's source is buyBook SOAP Request step's Request and its target is also buyBook SOAP Request step's request as we are modifying the existing node in buyBook request]
Property Transfer Source Window Code when inserting a node:
let $x:= //buyBook[1]/book[1]
return
<book>
<id>{$x/id/text()}</id>
<name>{$x/name/text()}</name>
<author>{$x/author/text()}</author>
<desc>{$x/desc/text()}</desc>
<paymentDetails>
<totalPrice>{$x/paymentDetails/totalPrice/text()}</totalPrice>
<frequentBuyerCard>BN-987654321</frequentBuyerCard>
</paymentDetails>
</book>
If you notice above, all we are doing is recreating the book node and populating its children elements and nodes up until we come across payment details where we hard code our frequentBuyerCard node ( that is insert it at this point ), the return statement returns this entire book node to be transferred to target ( which in this case is same as before : the very same node from buyBook request ). Do remember to check ON the option “Use XQuery” in this property transfer.
Property Transfer Target Window Code when inserting a node:
//buyBook[1]/book[1]
A better way to insert a node like shown above using XQuery is by issuing a statement like
insert node abcd as last into $x
This way one need not re-create the entire node. However soapUI Pro (2.5) as of this writing does not support this behavior. i.e. dynamic insert/updates using XQuery.
Update – Feb 17, 2009:
As per soapUI support, it seems soapUI 2.5 Pro currently uses Saxon 9 XQuery processor and Saxon 9.1 supports the the dynamic insert as I discussed a few lines above. So I hope in the future, the newer version of soapUI Pro using Saxon 9.1, shall be able to support actual dynamic insert of nodes. So watch out for soapUI’s newer version that may use Saxon 9.1 !
Hope that helps.
~srs
February 13, 2009 at 8:01 am
Very Cool!
To make the frequentBuyerCard value dynamic you could even replace it with a standard soapUI property-expansion, maybe referring to a datasource, testcase or project level property.. ie something like
${DataSource#buyerCard}
(this will be expanded before running the XQuery expression)
Thanks again!
/Ole
eviware.com
February 14, 2009 at 4:37 pm
Correct, Ole. It is indeed a good idea to store data like hard coded test-card values in some other step so that it is accessible throughout the test case.
It can also be stored in a Properties Step and acessed via:
${Properties#buyerCard}
Thanks, Ole.
-Sachin
April 18, 2009 at 7:26 pm
[...] “Use XQuery” when using X Query in property transfers: In one of my earlier posts on Property Transfers using XPath and XQuery, I had explained how to use XQuery expression in property transfers in soapUI. Figure below shows [...]