SoapUI how to get property transfer TestStep in Script Assertion of the next step - groovy

I'm using SoapUi 5.3.0 to test a case like this:
I have 3 apis: Book list, Add a book to favorite list, and Favorite list.
I add 3 apis to a TestCase as TestSteps to test the case: User views book list, choose the first book in the list then adds to favorite list, after that user goes to favorite list to verify that the book is displayed in the first place in Favorite list.
I add a propertyTransfer between step 1 and step 2, to get book_id from respond of step 1, then use to a param of the next step's request.
At step 3, I add an assertion by Script Assertion like below:
import groovy.json.JsonSlurper
//get propertyTransfer value
def tcProperty = messageExchange.modelItem.testStep.testCase.getTestStepByName("propertyTransfer").getPropertyValue("book_id")
// get response message of Favorite book api
def responseMessage = messageExchange.response.responseContent
// get book_id of the first book in favorite list
def jsonSlurper = new JsonSlurper().parseText(responseMessage)
bookId = jsonSlurper.data[0].book_id
// verify
assert bookId == tcProperty
But the script returns failed, and an error displays like attach photo
It seems tcProperty is null, means I could not get propertyTransfer value.
So where am I wrong?

You can either use Property Transfer test step or without it i.e., using Script Assertion for the request step itself.
If Script Assertion is used, then Property Transfer step is not needed at all.
The idea is extract the required value, and set it at test case level custom property in the Script Assertion.
Now, you want to use the above extracted value in the next step, which can be done using property expansion.
Here is the script assertion:
//Check if the response is not empty
assert context.response, 'Response is empty or null'
def jsonSlurper = new groovy.json.JsonSlurper().parseText(context.response)
bookId = jsonSlurper.data[0].book_id
assert bookId, 'Book id is empty or null'
//Set the bookId as test case level property
context.testCase.setPropertyValue('BOOK_ID', bookId)
In the next step, use property expansion i.e., ${#TestCase#BOOK_ID} where ever you needed book id

Related

Get/Update "REST Request Properties" value in SOAPUI is coming NULL

I am trying to get the Property value and Set it with different value in SoapUI's "REST Request Properties" (NOT the custom properties). It just gives me NULL value
Here is what I did:
1. Get test step object
2. get the property value with name of the property => It is giving me null value.
I know I am getting the correct object as I was able to rename the same Test Step name with following code
def restRequest = testRunner.testCase.getTestStepByName("Test");
def a = restRequest.getPropertyValue("Method")
log.info(a) // this gives null
restRequest.setName("Test1") // This works
In the step object, there is another object called testRequest from which you can get all those required properties.
For example if you want to get all the properties
log.info step.testRequest.metaClass.methods*.name
For example if you want to know the get methods
log.info step.testRequest.metaClass.methods*.name.findAll {it.startsWith('get')}
Similarly you can get the methods to set the value as well.
For instance, you want to modify Pretty Print from true to false:
step.testRequest.setPrettyPrint(false)
log.info step.testRequest.properties['prettyPrint']
Similarly, you can find the required property name, find the right method to modify the value as per your needs.

conditional execution of particular teststep according to result of previous request

I use SOAP UI Free.
I want to verify if previous response returns number (id) and conditionally run particular teststep.
My pseudocode below. How can I achieve this action using groovy?
How can I get response and verify if contains number and returns 200?
How can I extract this number and use it as parameter in next request
How can I compare if response is true?
response sample (200) :
523455
response sample (404) :
{
"category": "BUSINESS",
"code": "NOT_FOUND",
"description":"Account not found",
"httpStatus": 404
}
1.step GET accountId
2.step GROOVY
if(accountId is number and returns 200){
extract this number from json
run testRunner.testStep("removeAccount) for extracted number
if(response.equals("true"){
testRunner.runTestStep("createNewAccount")
}
}
1 - Use a property transfer step :
Target the id using JSONPath (should be something like "$.id")
Set "Set null on missing source" to true
Store it in a custom property of your testCase (e.g. "curId")
Additionally, if you want the Http status code, you should store it with a groovy script in another custom variable using something like this :
curHeaders = testRunner.testCase.testSteps["Get token"].testRequest.response.getResponseHeaders()
testRunner.testCase.setPropertyValue("http status", curHeaders["#status#"][0])
2 - Using a groovy script step :
Retrieve the variables above :
curId = testRunner.testCase.getPropertyValue("curId")
curHttpStatus = testRunner.testCase.getPropertyValue("http status")
Test those variables and run test step "removeAccount" if true:
if(curId && (curHttpStatus == 'HTTP/1.1 200 OK'))
{
removeActionTestStep = testRunner.testSteps["removeAccount"]
removeActionTestStep.run(null, false)
}
Note : removeAccount test step should make reference to curId custom variable (e.g. using "${#TestCase#curId}) so it runs with this id
You can add the createAccount part after the removal using jsonSlurper
removeActionResultJSON = context.expand('${removeAccount#Response}')
removeActionResultJSONSlurper = new groovy.json.JsonSlurper().parseText(removeActionResultJSON )
Then target where your response will make it equal true, then use another if - run statement like below.
Hope this helps,
Thomas

How to check if a value displays in particular format in XML response in soapui

I am trying to use using script assertion or by groovy code to check if a value under an element in xml response exits in particular format.
Sample response :
<ns5:price>99.99</ns5:price>
<ns5:date>2016-04-04</ns5:date>
<ns5:quantity>1</ns5:quantity>
For example, I want to check if any price exists and in format 5,4, same for date to see if date in format yyyy-mm-dd and quantity is not 0.
All the values are dynamic.
I am wondering if we can use using a script assertion or can use point and click with soap ui pro.
I am just learning soapui pro and groovy.
Thanks.
You can create an script assertion in your SOAP testStep and make the validations there. In the script assertion you can parse the response using a XmlSlurper, then get the desired nodes using findAll and perform all the asserts. You can do it using something like:
// from script assertion get the response
def response = messageExchange.getResponseContent()
// parse the XML
def xml = new XmlSlurper().parseText(response)
// get all prices
def prices = xml.'**'.findAll { it.name() == 'price' }
// check that each one has at "max 5 digits.max 4 digits"
prices.each { assert it ==~ /\d{0,5}\.\d{0,4}/ }
// get all dates
def date = xml.'**'.findAll { it.name() == 'date' }
// check the date has yyyy-MM-dd format
date.each { assert it ==~ /\d{4}\-\d{2}\-\d{2}/ }
// get all quantities
def quantity = xml.'**'.findAll { it.name() == 'quantity' }
// check that all quantities are > 0
quantity.each { assert it.text().toInteger() > 0 }
NOTE: To add an script assertion to your request, click on Assertions tab on left down corner of your SOAP Request panel:
Then right click on it and select add Assertion:
In a new panel select Script from a left side menu and then Script Assertion on the right options:
Finally use the code provided and make your checks :):

access response in SOAP UI in Groovy Script

I am new to Groovy Scripting. I am trying to access the value of a Response node
below is the script
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context);
def responseHolder = groovyUtils.getXmlHolder( testRunner.testCase.testSteps["request"].testRequest.response.responseContent );
responseHolder.namespaces["ns0"]="http://xmlns.int.com/orders/xsd/v1"
String mySection = responseHolder.getNodeValue["//ns0:MT_OrderCreateDTCFulfillmentResponse/ns0:StatusCode"] ;
log.info mySection
mySection is printed as []
Response XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header xmlns:v1="http://xmlns.int.com/orders/xsd/v1"/>
<soapenv:Body xmlns:v1="http://xmlns.int.com/orders/xsd/v1">
<ns0:MT_OrderCreateDTCFulfillmentResponse xmlns:ns0="http://xmlns.int.com/orders/xsd/v1">
<StatusCode>000</StatusCode>
<ReferenceDocNbr>NA</ReferenceDocNbr>
<SchemaValidationStatus>Validated</SchemaValidationStatus>
<StatusTimestamp>2015-08-03T18:58:01.602</StatusTimestamp>
<FaultDetails>Request for customer order number NA received successfully and format validated.</FaultDetails>
</ns0:MT_OrderCreateDTCFulfillmentResponse>
</soapenv:Body>
</soapenv:Envelope>
SOAP UI Project Structure - I am running Test_Script. Suggest me what i am missing
You've to use:
responseHolder.getNodeValue("//ns0:MT_OrderCreateDTCFulfillmentResponse/StatusCode");
instead of responseHolder.getNodeValue["//ns0:MT_OrderCreateDTCFulfillmentResponse/ns0:StatusCode"];
Note that I change responseHolder.getNodeValue invocation to use () instead of [], and also change your xpath since in your response <StatusCode> it's not defined in xmlns:ns0="http://xmlns.int.com/orders/xsd/v1".
Another option is to use the * wildcard as a namespace to map anyone. So in this case you can use:
responseHolder.getNodeValue("//*:MT_OrderCreateDTCFulfillmentResponse/*:StatusCode");
Additionally, note that probably you XML is wrong, since I suppose that all sub elements of <MT_OrderCreateDTCFulfillmentResponse> must belongs to "http://xmlns.int.com/orders/xsd/v1" namespace... so you've to declare it as:
<ns0:MT_OrderCreateDTCFulfillmentResponse xmlns:ns0="http://xmlns.int.com/orders/xsd/v1">
<ns0:StatusCode>000</ns0:StatusCode>
<ns0:ReferenceDocNbr>NA</ns0:ReferenceDocNbr>
<ns0:SchemaValidationStatus>Validated</ns0:SchemaValidationStatus>
<ns0:StatusTimestamp>2015-08-03T18:58:01.602</ns0:StatusTimestamp>
<ns0:FaultDetails>Request for customer order number NA received successfully and format validated.</ns0:FaultDetails>
</ns0:MT_OrderCreateDTCFulfillmentResponse>
Or using as default for this tag:
<MT_OrderCreateDTCFulfillmentResponse xmlns="http://xmlns.int.com/orders/xsd/v1">
<StatusCode>000</StatusCode>
<ReferenceDocNbr>NA</ReferenceDocNbr>
<SchemaValidationStatus>Validated</SchemaValidationStatus>
<StatusTimestamp>2015-08-03T18:58:01.602</StatusTimestamp>
<FaultDetails>Request for customer order number NA received successfully and format validated.</FaultDetails>
</MT_OrderCreateDTCFulfillmentResponse>
Note that if you change you XML with my indication your first XPath it's correct since now StatusCode belongs to your namespace.
Hope it helps,

return codes for Jira workflow script validators

I'm writing a workflow validator in Groovy to link two issues based on a custom field value input at case creation. It is required that the custom filed value to Jira issue link be unique. In other words, I need to ensure only one issue has a particular custom field value. If there is more than one issue that has the input custom field value, the validation should fail.
How or what do I return to cause a workflow validator to fail?
Example code:
// Set up jqlQueryParser object
jqlQueryParser = ComponentManager.getComponentInstanceOfType(JqlQueryParser.class) as JqlQueryParser
// Form the JQL query
query = jqlQueryParser.parseQuery('<my_jql_query>')
// Set up SearchService object used to query Jira
searchService = componentManager.getSearchService()
// Run the query to get all issues with Article number that match input
results = searchService.search(componentManager.getJiraAuthenticationContext().getUser(), query, PagerFilter.getUnlimitedFilter())
// Throw a FATAL level log statement because we should never have more than one case associated with a given KB article
if (results.getIssues().size() > 1) {
for (r in results.getIssues()) {
log.fatal('Custom field has more than one Jira ssue associated with it. ' + r.getKey() + ' is one of the offending issues')
}
return "?????"
}
// Create link from new Improvement to parent issue
for (r in results) {
IssueLinkManager.createIssueLink(issue.getId(), r.getId(), 10201, 1, getJiraAuthenticationContext().getUser())
}
try something like
import com.opensymphony.workflow.InvalidInputException
invalidInputException = new InvalidInputException("Validation failure")
this is based of the groovy script runner. If it doesn't work for you, i would recommend you using some sort of framework to make scripting easier, I like using either groovy script runner , Jira Scripting Suite or Behaviours Plugin
. All of them really makes script writing easier and much more intuitive.

Resources