How to access dynamic values in script assertion; which are set at test case level? - groovy

I have set a dynamic value at test case level for the below response.
{
"orderDetails": {"serviceOrderNumber": "SO-EUAM-MX-EUAM-16423"},
"transactionDetails": {
"statusMessage": "Success",
"startRow": "1",
"endRow": "400",
"totalRow": "1",
"timeZone": "EST"
},
"customerNodeDetails": {
"startDate": "20180622 06:32:39",
"nodeCreateDate": "20180622 06:32:39",
"customerId": "5562"
}
}
assert context.response, 'Response is empty or null'
def json = new groovy.json.JsonSlurper().parseText(context.response)
context.testCase.setPropertyValue('CustID', json.customerNodeDetails.customerId.toString())
Now while asserting another API which is a GET one, I am getting the CustID as customerNumber.
I have used the below code:
assert json.customerNodeDetails.customerNumber == "${#TestCase#CustID}"
and the block of response for the same was:
"customerNodeDetails": {
"nodeLabel": null,
"customerNumber": "5544",
"customerName": "ABCDEFGHIJ ABCDEFGHIJ LMNOPQRSTUV1234",
"taxIdCity": "",
"taxIdState": "",
"salesSegment": "Government",
"dunsNumber": "",
"mdsId": "",
"accountClassification": "B",
"specialCustomerBillCode": ""
}.
But I am getting the below error as:
startup failed: Script65.groovy: 26: unexpected char: '#' # line 26, column 54. eDetails.customerNumber == "${#TestCase# ^ org.codehaus.groovy.syntax.SyntaxException: unexpected char: '#' # line 26, column 54. at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:138) at
Please let me know how to access that value.

If you're referring to a property within a Groovy script, you can't use it directly as you might in other parts of the UI. You need to expand it:
def custID = context.expand('${#TestCase#CustID}')
Or, the messageExchange variable available in script assertions gives you an alternative way to do the same thing:
def alternative = messageExchange.modelItem.testStep.testCase.getPropertyValue('CustID');
Then, if you need a property that's defined somewhere else other than at the test-case level, you can use:
def projectLevelProperty = messageExchange.modelItem.testStep.testCase
.testSuite.project.getPropertyValue('projectLevelProperty');

Related

Groovy slurper.parser variable of a variable

Here is the snippet of my groovy script:
jsonFileData = slurper.parse(jsonFile)
Here is my JSON file
{
"MEMXYZ": {
"LINKOPT": {
"RMODE": "31",
"AMODE": "ANY"
},
"PROCESSOR": "PROCESSOR XYZ",
"DB2": {
"OWNER": "USER1",
"QUALIFER": "DB2ADMIN",
"SSID": "DBC1"
},
"COBOL": {
"VERSION": "V6",
"CICS": "V5R6M0",
"OPTIONS": "LIST,MAP,RENT",
"DB2": "YES"
}
}
}
println "Print1 ***** Parsing PROCESSOR = ${jsonFileData.MEMXYZ.PROCESSOR}"
println "Print2 ***** Parsing PROCESSOR = ${jsonFileData}.${Member}.PROCESSOR"
The Print1 is working fine with with explicit Member name "MEMXYZ", but I have problem with Print2, which I need to have the dyanmic ${Member} variable substitution. Please help!
${Member} is MEMXYZ
Please help to solve the Print2 statement
".. ${abc} ..." just injects the value of abc variable into string.
To access values of map (result of slurper.parse(...) in your case) you could use one of approaches:
jsonFileData[Member].PROCESSOR
jsonFileData[Member]['PROCESSOR']
So, your print line could look like:
println "PROCESSOR = ${jsonFileData[Member].PROCESSOR}"

Groovy to round all array decimal places down and return unique number count?

Thank you aspok for your help!
My goal is to get my list to be [3, 3, 4] and then get a count of unique values within it. Can anyone point me in the right direction for doing this?
My script consumes a JSON and puts all F4211_LNID values into a list. [3.1, 3.9, 4]. I need to now round all decimal places down.
I'm not sure if it's doable, but I am trying to use Math.floor(intListItems) to round my array values down. When I try this I receive the following error: Exception No signature of method: static java.lang.Math.floor() is applicable for argument types: (ArrayList) values: [[3.1, 3.9, 4]] Possible solutions: floor(double), log(double), find(), macro(groovy.lang.Closure), acos(double), cos(double)
I see my simplified list in the error, but I can't get it to round down and not sure what the error means.
(UPDATED) My Working Groovy
// Read Input Values
String aInputJson = aInputMap.InputJson ?: "{}"
// Initialize Output Values
def intListItems = []
def uniqueCount = 0
// Parse JSON
def json = new JsonSlurper().parseText( aInputJson )
// Determine Row Numbers
def rowset = json?.fs_DATABROWSE_F4211?.data?.gridData?.rowset
intListItems = rowset.collect{ Math.floor(it.F4211_LNID) }
intListItems.unique()
uniqueCount = intListItems.size()
JSON I am using.
{
"fs_DATABROWSE_F4211": {
"title": "Data Browser - F4211 [Sales Order Detail File]",
"data": {
"gridData": {
"id": 58,
"fullGridId": "58",
"rowset": [
{
"F4211_LNTY": "S",
"F4211_CPNT": 0,
"F4211_MCU": " 114000",
"F4211_DSC2": "NAS133N3EK166",
"F4211_NXTR": "580",
"F4211_LNID": 3.1,
"F4211_DOCO": 2845436
},
{
"F4211_LNTY": "S",
"F4211_CPNT": 0,
"F4211_MCU": " 114000",
"F4211_DSC2": "NAS133N3EK166",
"F4211_NXTR": "580",
"F4211_LNID": 3.9,
"F4211_DOCO": 2845436
},
{
"F4211_LNTY": "S",
"F4211_CPNT": 0,
"F4211_MCU": " 114000",
"F4211_DSC2": "NAS133N3EK166",
"F4211_NXTR": "580",
"F4211_LNID": 4,
"F4211_DOCO": 2845436
}
],
"summary": {
"records": 1,
"moreRecords": false
}
}
},
"errors": [],
"warnings": []
},
"currentApp": "DATABROWSE_F4211",
"timeStamp": "2000-06-01:09.42.02",
"sysErrors": []
}
You are getting the error Exception No signature of method: static java.lang.Math.floor() is applicable for argument types: (ArrayList) because there is no version of Math.floor() that accepts a List as a parameter.
Instead, you need to call Math.floor() on each individual item in the list. The easiest way to do this is in the collect { } call you are already doing.
def flooredList = rowset.collect { Math.floor(it.F4211_LNID) }
assert flooredList == [3.0, 3.0, 4.0]

Groovy and Spring Cloud Contract - Variable in the bodyAsValue

I would like to know how am I supposed to create in Groovy the Json payload with a random value.
For example
Contract.make {
name"MyFirstContract"
description "A description"
request {
method "POST"
url "/api/team/createTeam"
headers {
contentType applicationJson()
accept applicationJson()
header"Authorization", execute('bearerOfAccessToken()')
}
body """ {
"authenticatedUserCode":"papas",
"input": {
"name":"${execute('generateTeamUniqueName()')}",
"teamDefinitionName": "JUNIT TEST NAME",
"context":"context AHO",
"description":"team Description",
"members":
[
{"role":"Junit Reviewer",
"memberType":"USER",
"reference":"papas"
},
{"role":"Junit Observer",
"memberType":"USER",
"reference":"papas"
},
{"role":"Junit Collaborator",
"memberType":"USER",
"reference":"papas"
},
{"role":"Junit Reviewer",
"memberType":"USER",
"reference":"papas"
}
]
} } """
}
The important part from the previous code is the following that fails during compilation.
"name":"${execute('generateTeamUniqueName()')}",
with the following error message:
Execution default-generateTests of goal org.springframework.cloud:spring-cloud-contract-maven-plugin:3.0.2:gener
ateTests failed: expecting '}' or ',' but got current char 'E' with an int value of 69
Is it possible to call a method inside the body or I have to return the ALL the contents of the body through the same method???
Thank you!
You have to call it for the whole body, it won't work for part of it

Jmeter Groovy replacing JSON file

In Jmeter JSR223Preprocessor with Groovy I load a generic JSON file xyz looking like this:
{
"name": "dummy",
"block1": {
"var1": 1,
"var2": {
"value": 1,
"unit": "Miles",
},
"var3": {
"value": 3,
"unit": "Seconds",
},
"myList": [{"Id": 0}]
}
I like to come up with an elegant way to replace the var2 "Value" with a configurable value sayconfVal. This works:
String path = vars.get("basePath")+"xyz.json" ;
xyz = new File(path).getText("UTF-8");
xyz = xyz.replaceAll ('"value": 1', '"value": ${confVal}');
However I am not comfortable with this because it is vulnerable with spaces, and moreover I have another Value on var3 and someone could accidentally change 1 to 3. So I like to index to that child var2.Value then get Value.
Thank you
Add JSR223 PreProcessor as a child of the HTTP Request which body you need to amend
Put the following code into "Script" area:
def xyz = new File(vars.get("basePath")+"xyz.json")
def request = new groovy.json.JsonSlurper().parse(xyz)
request.block1.var2.value=vars.get('confVal') as int
xyz.newWriter().withWriter { writer ->
writer << new groovy.json.JsonBuilder(request).toPrettyString()
}
That's it, the value in the file should be replaced with what you have in the ${confVal} variable in the runtime.
More information:
Groovy: Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

Parsing child nodes of JSON response in SOAP UI using groovy json slurper

I am getting a JSON response from an webservice like below . I want to parse all childs of results node using Groovy Json slurper and assert the value is correct.
{
"status": "Healthy",
"results": [
{
"name": "Microservice one",
"status": "Healthy",
"description": "Url check MSOneURI success : status(OK)"
},
{
"name": "Microservice two",
"status": "Healthy",
"description": "Url check MSTwoURI success : status(OK)"
},
{
"name": "Microservice three",
"status": "Healthy",
"description": "Url check MSThreeURI success : status(OK)"
},
{
"name": "Microservice four",
"status": "Healthy",
"description": "Url check MSFourURI success : status(OK)"
},
{
"name": "Microservice five",
"status": "Healthy",
"description": "Url check MSFiveURI success : status(OK)"
}
]
}
This is what I have done - this works .
//imports
import groovy.json.JsonSlurper
import groovy.json.*
//grab the response
def ResponseMessage = messageExchange.response.responseContent
// trim starting and ending double quotes
def TrimResponse =ResponseMessage.replaceAll('^\"|\"$','').replaceAll('/\\/','')
//define a JsonSlurper
def jsonSlurper = new JsonSlurper().parseText(TrimResponse)
//verify the response to be validated isn't empty
assert !(jsonSlurper.isEmpty())
//verify the Json response Shows Correct Values
assert jsonSlurper.status == "Healthy"
def ActualMsNames = jsonSlurper.results*.name.toString()
def ActualMsStatus = jsonSlurper.results*.status.toString()
def ActualMsDescription = jsonSlurper.results*.description.toString()
def ExpectedMsNames = "[Microservice one,Microservice two,Microservice three,Microservice four,Microservice five]"
def ExpectedMsStatus = "[Healthy, Healthy, Healthy, Healthy, Healthy]"
def ExpectedMsDescription = "[Url check MSOneURI success : status(OK),Url check MSTwoURI success : status(OK),Url check MSThreeURI success : status(OK),Url check MSFourURI success : status(OK),Url check MSFiveURI success : status(OK)]"
assert ActualMsNames==ExpectedMsNames
assert ActualMsStatus==ExpectedMsStatus
assert ActualMsDescription==ExpectedMsDescription
But I want to make it better using some kind of for loop which will parse each collection one at a time and assert the value of "name", "status" and "descriptions" at once for each child
Is that possible?
Yes, that's certainly possible.
Without knowing more about your actual data it's not possible to give a perfect example, but you could do something like:
jsonSlurper.results?.eachWithIndex { result, i ->
assert result.name == expectedNames[i]
assert result.status == expectedStatus[i] // or just "Healthy" if that's the only one
assert result.description == expectedDescriptions[i]
}
where expectedWhatever is a list of expected result fields. If your expected results really are based on index like in your example, then you could even calculate them within the loop, but I'm guessing that's not the case for real data.

Resources