I have the below groovy script which I run in groovyconsole and it runs just fine. I'm finding the number of child nodes for a particular node in my xml response and printing out required values for each child node.
def path = new XmlSlurper().parse(new File('C://SoapUI//ResponseXML/Response.xml'))
NumberOfPositions = path.Body.GetPositionsAggregateResponse.GetPositionsAggregateResult.AccountPositions.Securities.Positions.children().size()
for(def i=0; i<NumberOfPositions; i++){
println i
println path.Body.GetPositionsAggregateResponse.GetPositionsAggregateResult.AccountPositions.Securities.Positions.PositionSummary[i].Legs[0].PositionAggregate[0].PositionID[0].text()
println path.Body.GetPositionsAggregateResponse.GetPositionsAggregateResult.AccountPositions.Securities.Positions.PositionSummary[i].Legs[0].PositionAggregate[0].AccountID[0].text()
}
I want to perform the same task in soapUI, but couldn't get it working using groovyutils as mentioned here : http://www.soapui.org/Scripting-Properties/tips-a-tricks.html
1) How do I parse the xml response from my request to xmlSlurper?
def path = new XmlSlurper().parse (?)
2) Would I be able to use the same code above in soapUI too?
Any help is appreciated. Thanks!
(1)
For parsing the response message you could try the following:
def response = context.expand( '${TestRequest#Response}' )
def xml = new XmlSlurper().parseText(response)
TestRequest represents the name of your test step which is sending the SOAP request message.
(2)
Yes, soapUI should be able to handle any Groovy code.
You can directly use normal groovy script in SoapUI. Check this link, it might help you. But, remember that instead of "println' You need to use "log.info" while scripting in SoapUI.
Related
I have two HTTP GET requests in Jmeter. The first one calls to a server and gets a CSV that holds some user data. Using a JSR223 Post processor, I am , mapping that data onto a JSON and assigning the values to three variables to be passed onto the second request. The script for doing that is below.
import org.apache.commons.io.IOUtils
import java.nio.charset.StandardCharsets
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
def response = prev.getResponseDataAsString()
def lines = response.split('\n')
def userData = []
for (int i = 1; i < lines.length; i++) {
def line = lines[i]
def tokens = line.split(',')
userData << [login_type: tokens[0], username: tokens[1], password: tokens[2]]
}
def jsonString = JsonOutput.toJson(userData)
def jsonSlurper = new JsonSlurper()
def jsonMap = jsonSlurper.parseText(jsonString)
for (int i = 1; i <= Math.min(jsonMap.size(), Integer.parseInt("${__P(threads)}")); i++) {
if(i < jsonMap.size()){
vars.put("login_type" , jsonMap[Integer.parseInt("${__threadNum}")-1].login_type)
vars.put("username" , jsonMap[Integer.parseInt("${__threadNum}")-1].username)
vars.put("password" , jsonMap[Integer.parseInt("${__threadNum}")-1].password)
}
}
I pass these three variables in the next request body as {"login_type":"${login_type}","username":"${username}","password":"${password}"}
When running the script i'm getting the response as 400 for second request even though i can see the data is getting passed.
POST data:
{"login_type":"data","username":"data","password":"data"}
I tried the second request by manually giving the login data instead of the variables and it works.
{"login_type":"EMAIL","username":"username","password":"pass"}
The only difference i see on both attempts is in the request header where the Content-Length: 83 is shown for when manually sending data and Content-Length: 84 is shown for when passing the data from the groovy script. Though i don't think that's what causing the issue. Can anyone explain as to why this is happening and how to fix this.
I looked into the requests and the POST request body coming from the groovy script has a line break at the end.
{"login_type":"login_type","username":"username","password":"password
"}
Hence causing the request to throw a 400. How can i send the body data in one line?
Maybe there is some invisible character like whitespace or line break which is expected by your system under test and which you're not sending when you're populating variables in Groovy.
Use a sniffer tool like Wireshark or Fiddler to compare both requests byte by byte and amend your JMeter configuration or Groovy code to 100% match the "manual" request.
Also regarding your usage of JMeter Functions in the script, according to JSR223 Sampler documentation:
The JSR223 test elements have a feature (compilation) that can significantly increase performance. To benefit from this feature:
Use Script files instead of inlining them. This will make JMeter compile them if this feature is available on ScriptEngine and cache them.
Or Use Script Text and check Cache compiled script if available property.
When using this feature, ensure your script code does not use JMeter variables or JMeter function calls directly in script code as caching would only cache first replacement. Instead use script parameters.
So replace:
${__P(threads)} with props.get('threads')
${__threadNum} with ctx.getThreadNum()
See Top 8 JMeter Java Classes You Should Be Using with Groovy for more information on what do these props and ctx guys mean.
I have a requirement in which I need to print XML response in Groovy Script test step
Name of SOAP Request test step is Licensed
When I write
log.info context.expand('${Licensed#Response}')
I get right response
But I have a requirement where user is not aware of the code
def requestname=Licensed //user will enter request name here
log.info context.expand($'{requestname"#Response}')
I don't get valid response
I want to declare a variable and use and print xml response
Here is what you need in order use the step name as parameter / variable. You have a trivial error in your code snippet.
//You missed quotes
def requestname='Licensed'
//Your were using quotes incorrectly
log.info context.expand('${'+requestname+'#Response}')
Hope this resolves your issue.
Is there any way in which I can run a Property Transfer step from a groovy script? Both are in the same test case.
Test case contains the following test steps:
groovy script
soapUI request (GetAccountNumber)
property transfer step (transfers a response property from above to a request property in the below step)
soapUI request (DownloadURL)
I need to make sure that the flow is as follows:
Groovy runs and reads numbers from a file and passes them to GetAccountNumber.
GetAccountNumber runs with the passed values and generates a response.
This response is passed by the property transfer step to DownloadURL.
DownloadURL runs with this passed value and generates an output.
All I need to do is run the Property Transfer from the groovy because the other steps can be run from groovy.
It isn't running with the following code
def testStep_1 = testRunner.testCase.getTestStepByName("PropertyTransfer")
def tCase_1 = testRunner.testCase.testSuite.testCases["SubmitGenerateReport"]
def tStep_1 = tCase.testSteps["PropertyTransfer"]
tStep_1.run(testRunner, context)
Without more context I think that your problem is a simple typo, you get your testCase and assing to tCase_1:
def tCase_1 = testRunner.testCase.testSuite.testCases["SubmitGenerateReport"];
However then to get the tStep_1 you use tCase instead of tCase_1:
def tStep_1 = tCase.testSteps["PropertyTransfer"]; tStep_1.run(testRunner, context);
Additionally if the testStep you want to run from groovy are in the same testCase you're executing; you can run it simply using:
testRunner.runTestStepByName('some teststep name')
Which I think it's more convenient than get the testStep from the testCase and then run it.
Hope it helps,
I am using SOAPUI FREE. My project requirement is to pick Request XML (as we may have in hundreds) from a location and use it as it is as a request. Is it possible using any feature or Groovy Scripting in Free version
If you have SOAP xml requests in some directory and you want to pick each file from there and create a new TestStep for each one, you can do the follow:
Create a new TestCase and add a new SOAP TestStep inside which will be used as a template to easily create the new ones, then add a a groovy TestStep an use the next code to create the new tests steps in the same TestCase (I put the comments in the code to explain how it works):
import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestRequestStepFactory
// get the current testCase to add testSteps later
def tc = testRunner.testCase;
// get the SOAP TestStep as template to create the other requests
def tsTemplate = tc.getTestStepByName("MyRequest");
// create the test step factory to use later
def testStepFactory = new WsdlTestRequestStepFactory();
// now get all the request from a specific location...
// your location
def directory = new File("C:/Temp/myRequests/")
// for each file in the directory
directory.eachFile{ file ->
// use file name as test step name
def testStepName = file.getName()
// create the config
def testStepConfig = testStepFactory.createConfig( tsTemplate.getTestRequest(), testStepName)
// add the new testStep to TestCase
def newTestStep = tc.insertTestStep( testStepConfig, -1 )
// set the request from the file content
newTestStep.getTestRequest().setRequestContent(file.getText())
};
I think that you're asking about the SOAP TestStep however note that this code is to create SOAP TestStep request, to create REST TestStep request or other kind of TestStep you must change the code related to the testStepFactory (WsdlTestRequestStepFactory).
Furthermore for me it's not clear in your question if you're asking about to create a test steps for each request or if you prefer to run all requests from a groovy script without create the test steps, if the second one is your intention you can use in groovy script the apache-http-client classes which are included in the SOAPUI to send the request from your directory.
Hope this helps,
I am trying the write a groovy script which get the result from the response of the first testStep and use it into the next testStep.
My web service returns the following response after a POST:
<Response xmlns="http://xxxxxx.xxx.xxxxx.xxx/cal-service/v1/users/">
<individual_id>83ecf411-0e3b-4e6b-9bc4-d4b5f6efed54</individual_id>
</Response>
I am trying to grab the and pass it to my next test in the test suite.
I am new with groovy and soapUI but what I started with is:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def responseHolder = groovyUtils.getXmlHolder("messageExchange.responseContent")
def individualId = responseHolder.getNodeValue("individual_id")
log.info(individualId)
I am getting the following error when i run the test suite and it reaches the groovy script:
I don't see your error in you post, but to grab something from a request - here's how you do it. The groovy script will return the id from your request.
def id = context.expand( '${REST Test Request#ResponseAsXml#declare namespace ns1=\'http://lshlx082a.sys.cigna.com/cal-service/v1/users/'; //ns1:individual_id[1]}' )
return id;
Replace the "REST Test Request" part with the name of your REST test step.
NOTE: I tried this with my own namespace, so I might have cut-and-pasted your namespace and declarations incorrectly. But this is the general approach.
You can use the Property transfer step to transfer values between responces