I have to Store multiple data's in the spock table . When ever required i have to pass the data through parameter value, according to that it should search in the spock table, pick corresponding data. Please see the code and correct it.
It would be very much helpful to me to implement my project.
def passW = "Publisher"
def "getPassword" (passW) {
expect:
if (secureKeyword == passW ) {
println "Result is " + encryptPass
}
where:
secureKeyword || encryptPass
"Author" || "aW50ZWxAMTIzNCE="
"Publisher" || "tsdwerDhV76wYCf="
}
Result should be : tsdwerDhV76wYCf=
You can store module data in the static (or #Shared) collection and filter test input in where section in findAll closure.
def static moduleCredentials = ["Author":"aW50ZWxAMTIzNCE=",
"Publisher":"tsdwerDhV76wYCf="]
#Unroll
def "Module #module.key login credentials test"(){
def moduleName = module.key
def modulePass = module.value
println(moduleName+":"+modulePass)
expect:
assert modulePass
where:
module << moduleCredentials.findAll {it.key=="Author"}.entrySet()
}
Related
I have a json file with values - {"testID":"smoke_01","testID":"smoke_02","testID":"smoke_04"}.
I read the values for testID and saved to array. Now I was trying to make it as a simple string like -
testcase = smoke_01,smoke_02,smoke_02. My code is below :
def props = readJSON file: 'input.json'
def list = []
props.each { key, value ->
list.push("$value")
}
echo "$list"
def asString = list.join(", ")
def testcase = asString.join(", ")
But when i print testcase - its printing as [smoke_01, smoke_02, smoke_04] . Please help me to understand where I am wrong.
Assuming you really have this invalid strange JSON (keys must be unique in an Object in basically every language you parse to, but yours are not), and that readJSON actually parses your custom JSON into something you can iterate over as if it were a Map... then, this should do what you want:
def props = readJSON file: 'input.json'
def testCase = props.values().join(', ')
println testCase
Assuming you use proper JSON
By proper JSON I mean something that does not break JSON semantics, hence can be parsed by any JSON parser, not your custom one.
You JSON file should look more like this:
{ "tests": [
{ "testID": "smoke_01" },
{ "testID": "smoke_02" },
{ "testID": "smoke_03" }
] }
In which case you would parse it with:
def json = new JsonSlurper().parse(new File('input.json'))
def testCase = json.tests.collect { it.testID }.join(', ')
println testCase
There are other ways to represent this in JSON, but you should study how JSON works and what suits you best depending on how it is going to be used.
Here's the JSON spec which is simple enough you can learn it in 20 minutes:
https://www.json.org/json-en.html
Properties ScreenshotResponse Snippet
<tns:TAResponse
xmlns:tns="http://webconnectivity.co.uk/">
<tns:SessionToken>84hjfutryh47849dkdhg9493493=</tns:SessionToken>
<tns:PartyId>1234</tns:PartyId>
<tns:ResponseType></tns:ResponseType>
<tns:MessageUUId>12341F17-ABC9-3E99-1D12-B8289POO2107</tns:MessageUUId>
<tns:Matches>
<tns:IntegrationServiceMatch>
<tns:InternalReference>2066856</tns:InternalReference>
<tns:ErrorsAndWarnings>
<tns:IntegrationServiceErrorCode>
<tns:ErrorCode>W000026</tns:ErrorCode>
<tns:Description>Settlement Date not within tolerance</tns:Description>
</tns:IntegrationServiceErrorCode>
<tns:IntegrationServiceErrorCode>
<tns:ErrorCode>E000033</tns:ErrorCode>
<tns:Description>Number on message does not match</tns:Description>
</tns:IntegrationServiceErrorCode>
<tns:IntegrationServiceErrorCode>
<tns:ErrorCode>E000001</tns:ErrorCode>
<tns:Description>NO likely matches</tns:Description>
</tns:IntegrationServiceErrorCode>
</tns:ErrorsAndWarnings>
</tns:IntegrationServiceMatch>
</tns:Matches>
</tns:TAResponse>
I have stored all these Errorcode and Description in a property step. I need to validate whether these Errorcode and Description in the response matches with the property step. (sequence is not a deal)
Can someone pls guide me through groovy?
Previously i had to validate only one errorcode and desc from the response. so i validated using below script.
def content = new XmlSlurper().parse(file)
def respType = content.Body.TAResponse.ResponseType.text()
def errAndWarn = content.Body.TAResponse.Matches.IntegrationServiceMatch
assert errAndWarn.size() == 1
for (def i=0;i<errAndWarn.size();i++)
{
assert errAndWarn[i].ErrorsAndWarnings.IntegrationServiceErrorCode.ErrorCode == "E000033"
assert errAndWarn[i].ErrorsAndWarnings.IntegrationServiceErrorCode.Description == "Number on message does not match"
}
You can use below Script Assertion for the SOAP Request test step itself, that will avoid additional Groovy Script test step.
This assumes that the name of the Properties test step name is Properties. If its name differs, then change in the script accordingly.
Script Assertion
//Change the name of the Properties test step below
def step = context.testCase.testSteps['Properties']
//check if the response is not empy
assert context.response, 'Response is empty or null'
//Parse the xml
def parsedXml = new XmlSlurper().parseText(context.response)
//Get the all the error details from the response as map
def errorDetails = parsedXml.'**'.findAll { it.name() == 'IntegrationServiceErrorCode'}.inject([:]){map, entry -> map[entry.ErrorCode.text()] = entry.Description.text(); map }
log.info "Error details from response : ${errorDetails}"
//loop thru xml error codes and verify against the properties of Properties Test Step
errorDetails.each { key, value ->
assert step.properties[key]?.value == value, "Unable to match value of the property ${key} "
}
EDIT: based on OP's comment
Groovy Script test step:
//Change the name of the Properties test step below
def step = context.testCase.testSteps['Properties']
//Parse the xml like you have in your script
def parsedXml = new XmlSlurper().parse(file)
//Get the all the error details from the response as map
def errorDetails = parsedXml.'**'.findAll { it.name() == 'IntegrationServiceErrorCode'}.inject([:]){map, entry -> map[entry.ErrorCode.text()] = entry.Description.text(); map }
log.info "Error details from response : ${errorDetails}"
//loop thru xml error codes and verify against the properties of Properties Test Step
errorDetails.each { key, value ->
assert step.properties[key]?.value == value, "Unable to match value of the property ${key} "
}
EDIT2: Based on additional requirement, adding below Groovy Script
//Change the name of the Properties test step below
def step = context.testCase.testSteps['Properties']
//Parse the xml like you have in your script
def parsedXml = new XmlSlurper().parse(file)
//Get the all the error details from the response as map
def errorDetails = parsedXml.'**'.findAll { it.name() == 'IntegrationServiceErrorCode'}.inject([:]){map, entry -> map[entry.ErrorCode.text()] = entry.Description.text(); map }
log.info "Error details from response : ${errorDetails}"
def failureMessage = new StringBuffer()
//Loop thru properties of Property step and check against the response
step.properties.keySet().each { key ->
if (errorDetails.containsKey(key)) {
step.properties[key]?.value == errorDetails[key] ?: failureMessage.append("Response error code discription mismatch. expected [${step.properties[key]?.value}] vs actual [${errorDetails[key]}]")
} else {
failureMessage.append("Response does not have error code ${key}")
}
}
if (failureMessage.toString()) {
throw new Error(failureMessage.toString())
}
You should be able to do:
content.Body
.TAResponse
.Matches
.IntegrationServiceMatch
.ErrorsAndWarnings
.IntegrationServiceErrorCode.each { node ->
println "Error code is ${node.ErrorCode.text()} and Description is ${node.Description.text()}"
}
I am new to groovy code. I have a map like this
response = {"data":{"--class":"java.util.HashMap","Enabled":false,"Adult":"[recursive reference removed]","TVMA":"[recursive reference removed]","Locks":[false,false,false,false,false,false],"PINEnabled":false,"AdvisoryLocks":[false,false,false,false,false,false,false,false,false,false,false,false],"safeSearch":"[recursive reference removed]","RatingLocks":[false,false,false,false,false,false]},"success":true}
Using groovy code I want to check the presence of the following keys:
Enabled,
Adult,
TVMA,
Locks,
PINEnabled,
AdvisoryLocks,
safeSearch,
RatingLocks,
I am using the following code:
for ( data in response.data ) {
println("-----------------------------------------")
assertNotNull(data.Enabled)
assertNotNull(data.Adult)
;;;;;;
.......
}
Am getting groovy.lang.MissingPropertyException: No such property: Enabled
How can I check the presence of the above keys from response map using groovy?
I think you can find keys value from the Json like below.
def slurper = new JsonSlurper()
def result = slurper.parseText(response)
assert result.data.Enabled != null
assert result.data.Enabled != ""
assert result.data.Adult != null
assert result.data.Adult != ""
I hope that will help you :)
How about using good'ol regexp?
String response = '{"data":{"--class":"java.util.HashMap","Enabled":false,"Adult":"[recursive reference removed]","TVMA":"[recursive reference removed]","Locks":[false,false,false,false,false,false],"PINEnabled":false,"AdvisoryLocks":[false,false,false,false,false,false,false,false,false,false,false,false],"safeSearch":"[recursive reference removed]","RatingLocks":[false,false,false,false,false,false]},"success":true}'
assert [ 'Enabled', 'Adult', 'TVMA',,,, ].every{ response =~ /"$it":/ }
I'm a Groovy noob and trying to get my head around using reusable functions to extract an xml node value for a given test step and node in SoapUI. It seems the class runs fine but the problem is when using the method. I get the following error:
groovy.lang.MissingMethodException: No signature of method: org.apache.log4j.Logger.info() is applicable for argument types: (java.lang.String, java.lang.String) values: [return TestStepName, Node] Possible solutions: info(java.lang.Object), info(java.lang.Object, java.lang.Throwable), any(), wait(), dump(), find(groovy.lang.Closure) error at line:
This is my class:
class Example
{
def log
def context
def responseSOAXmlStep
def resultValue
def responseNodePath
def storeProperty
// Class constructor with same case as Class name
def Example(logIn,contextIn,testRunnerIn)
{
this.log = logIn
this.context = contextIn
this.responseSOAXmlStep = responseSOAXmlStep
this.responseNodePath = responseNodePath
}
def execute(responseSOAXmlStep,responseNodePath)
{
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context );
// do some stuff to prove I've run with right context, etc.
log.info "return "+responseSOAXmlStep,responseNodePath
def holder = groovyUtils.getXmlHolder( responseSOAXmlStep+"#ResponseAsXml" );
resultValue = holder.getNodeValue( "//ns1:"+responseNodePath );
log.info("Node value: " + resultValue );
testRunner.testCase.testSuite.setPropertyValue(storeProperty, resultValue);
return execute
}
}
context.setProperty( "example", new Example( log, context, testRunner) )
log.info "Library Context:"+context
This is where I do the call in a step after the response step:
// get a reference to the library TestSuite
library = testRunner.testCase.testSuite.project.testSuites["Library"]
// find the module within the library
module = library.testCases["Library"].testSteps["Second Example_Class"]
// initialise the library; which places an instance of Example in the context
module.run(testRunner, context)
// get the instance of example from the context.
def example = context.example
// run the method, with parameter
log.info "example.execute(responseSOAXmlStep,responseNodePath) = " + example.execute("TestStepName","Node")
I've searched the forum but could not find an answer that suites my query. Any form of assistance is appreciated. Thanks.
Your error description says that you're invoking info() method on log passing two strings as and arguments, and this method doesn't exist.
The problem is easy to solve, pass one concatenated string with + as parameter instead of passing two strings. In your execute method inside your Example class use this:
def execute(responseSOAXmlStep,responseNodePath)
{
...
// USE + TO CONCATENATE STRINGS INSTEAD OF USE ,
log.info "return " + responseSOAXmlStep + responseNodePath
...
}
instead of:
def execute(responseSOAXmlStep,responseNodePath)
{
...
// do some stuff to prove I've run with right context, etc.
log.info "return " + responseSOAXmlStep,responseNodePath
...
}
EDIT:
As you said in your comment probably you've another problem storing properties in TestSuite level. You're using this code:
testRunner.testCase.testSuite.setPropertyValue(storeProperty, resultValue);
The problem is that setPropertyValue is expecting string as a first argument however at this line in your code storeProperty is not defined yet. Try for example defining storeProperty as:
def storeProperty = "myProperty" before using it in setPropertyValue call.
Hope this helps,
I have a groovy script that I've added code to to check if a value exists in an XML response I'm getting within SoapUI. I've been dealing with this for a few days and could use some help.
Here is the code:
import com.eviware.soapui.support.XmlHolder
import com.eviware.soapui.impl.wsdl.teststeps.registry.RestRequestStepFactory
// read your request template
def requestFile = new File("C:/XMLRequestScript/file.xml");
// parse it as xml
def requestXml = new XmlHolder(requestFile.text)
// get the current testCase to add testSteps later
def tc = testRunner.testCase;
// get the testStep as template to create the other requests
def tsTemplate = tc.getTestStepByName("Template");
// loop to create # of testSteps for each application
for(int i = 1; i < 3; i++) {
// xpath expression to get applicationNumber attribute in root node
def xpathNodeAttr = "/*/#ApplicationNumber";
// get the root node attribute applicationNumber throught an XPATH
int appId = Integer.parseInt(requestXml.getNodeValue(xpathNodeAttr));
// add 1 to appId
appId++;
// set the value again in the attribute
requestXml.setNodeValue(xpathNodeAttr,appId);
// create next testStepName for new Application
def testStepName = "TestStep_ApplicationNumber_" + String.valueOf(appId)
log.info testStepName;
log.info testStepName.getClass().getName()
log.info tc.getClass().getName()
// create a new testStepConfig
def testStepFactory = new RestRequestStepFactory();
def testStepConfig = testStepFactory.createConfig( tsTemplate.getTestRequest(), testStepName )
// add the new testStep to TestCase
def newTestStep = tc.insertTestStep( testStepConfig, -1 )
// set the request
newTestStep.getTestRequest().setRequestContent(requestXml.getXml())
// add Assertions here
def assertion = tc.getTestStepByName(newTestStep.toString()).addAssertion("Contains")
if (assertion.contains("Champion5")) {
newTestStep.addAssertion("Champion5")
log.info("REST response assertion created into: " + newTestStep)
} else {
log.info("REST response assertion not found in " + newTestStep)
}
if (assertion.contains("Challenger5")) {
newTestStep.addAssertion("Challenger5")
log.info("REST response assertion created into: " + newTestStep)
} else {
log.info("REST response assertion not found in " + newTestStep)
}
// execute the request
newTestStep.run(testRunner, context)
}
In the section above called "// add Assertions here", the line of code that I'm having a problem with is:
def assertion = tc.getTestStepByName(newTestStep.toString()).addAssertion("Contains")
The error states:
Thu Sep 18 14:27:57 CDT 2014:ERROR:An error occurred [Cannot invoke method addAssertion() on null object], see error log for details
My understanding is that I have to pass an Assertion Type that is contained in the SoapUI GUI and just put it in as a string value in order to check if the values that I'm checking are asserted.
Any suggestions/direction would be appreciated. I have no idea what I'm doing wrong. Thanks.
I think the problem is your are calling the function tc.getTestStepByName(String name) with a wrong name, because the newTestStep.toString() doesn't return the Test step name instead it returns the class name (it really returns 'classname' + '#' + 'Integer.toHexString(hashCode())' if it's not override it, see Object.toString()) .
Anyway what you want is to add an assertion for a test step which is just created so add the assertion directly to it instead to find it by name, use:
def assertion = newTestStep.addAssertion("Contains")
instead of:
def assertion = tc.getTestStepByName(newTestStep.toString()).addAssertion("Contains")
The second problem you have is that you're using the assertion incorrectly. The assertion object in your case is an instance of SimpleContainsAssertion and contains() method doesn't exist in this class, to set the string to check in contains assert use setToken() method, I think that you need this to add the two assertions:
def assertion = newTestStep.addAssertion("Contains")
// add token to check
assertion.setToken("Champion5")
// change assert name in order to avoid the popup
// when we create the second one.
assertion.setName("CONTAINS 1")
// create a second assertion
assertion = newTestStep.addAssertion("Contains")
assertion.setToken("Challenger5")
assertion.setName("CONTAINS 2")
instead of :
// add Assertions here
def assertion = tc.getTestStepByName(newTestStep.toString()).addAssertion("Contains")
if (assertion.contains("Champion5")) {
newTestStep.addAssertion("Champion5")
log.info("REST response assertion created into: " + newTestStep)
} else {
log.info("REST response assertion not found in " + newTestStep)
}
if (assertion.contains("Challenger5")) {
newTestStep.addAssertion("Challenger5")
log.info("REST response assertion created into: " + newTestStep)
} else {
log.info("REST response assertion not found in " + newTestStep)
}
This code will result creating this two asserts, one named "CONTAINS 1" and check that response contains the string "Champion5", and a second one named "CONTAINS 2" and check that response contains the string "Challenge5".
Hope this helps,