ahj.ashish ahj.ashish - 3 months ago 45
Groovy Question

Run a groovy string in a groovy script as a different script

there is a requirement where I am trying to port SOAP UI test suites to test as rest service written with groovy assertions to groovy test cases in a java maven project.

The approach is to parse the SOAP UI project xml file using XmlSlurper to get the request and other required details to fire a rest service and receive a response from the service and then use the same groovy assertions in SOAP UI to assert the response received using the groovy script.

This approach was decided because there are already thousands of test cases written in SOAP and we want to leverage the same.

While parsing the xml we can easily get the assertions from the xml in a variable as a string or a GPathResult to be specific.
What I am not able to figure out is how to get that assertions string to run as a assert script on the response received by my service.

Here is the code I was trying with :




DemoTest.groovy


package somepackage.groovy

import groovyx.net.http.ContentType
import groovyx.net.http.RESTClient

class Demotest extends GroovyTestCase {

void testFail() {
def client = new RESTClient('http://localhost:8080')
def xmlfile = new XmlSlurper().parse(new File('/path/to/soap-ui.xml'))
def endpoint = (xmlfile.testSuite.testCase[0].testStep[0].config.@service)
def resourcePath =(xmlfile.testSuite.testCase[0].testStep[0].config.@resourcePath)
def request = (xmlfile.testSuite.testCase[0].testStep[0].config.restRequest.request).text()
def assertion = (xmlfile.testSuite.testCase[0].testStep[0].config.restRequest.assertion).text()
def bodyMap = new groovy.json.JsonSlurper().parseText(request)
try {
def resp = client.post(
path: resourcePath,
body: bodyMap,
requestContentType: ContentType.JSON
)
println( resp.data )
// def jsonSlurper = resp.data
def asserts = assertion.substring(assertion.indexOf('assert').intValue())
String script = asserts
// .replaceAll('jsonSlurper','resp.data')
GroovyScriptEngine gse = new GroovyScriptEngine()
Binding binding = new Binding();
binding.setVariable('jsonSlurper', resp.data )
Object result = gse.run(script, binding)
println( result )
} catch (ex){
println( ex.printStackTrace() )
}
}
}



Soap UI assertions


//imports
import groovy.json.JsonSlurper
//grab the response
def ResponseMessage = messageExchange.response.responseContent
//define a JsonSlurper
def jsonSlurper = new JsonSlurper().parseText(ResponseMessage)
//asserts
assert jsonSlurper....
assert jsonSlurper....

Answer

I think for your case it's better to use GroovyShell instead of GroovyScriptEngine because it's easier to use to run scripts as Strings.

Supposing that you get correctly your Script assertion in def assertions variable you can run the script using the following code:

import groovy.json.JsonSlurper

...
...

def assertion = '''//imports
 import groovy.json.JsonSlurper
//grab the response
 def ResponseMessage = messageExchange.response.responseContent
//define a JsonSlurper
 def jsonSlurper = new JsonSlurper().parseText(ResponseMessage)
//asserts
assert jsonSlurper.field == 'value'
assert jsonSlurper.otherField == 'secondValue' '''

def script = assertion.substring(assertion.indexOf('//asserts').intValue())

Binding binding = new Binding(); 
def shell = new GroovyShell(binding)
binding.setProperty('jsonSlurper', new JsonSlurper().parseText('{"field":"value", "otherField" : "secondValue"}') )
shell.evaluate(script)

Also note that I change your substring condition to get a part of your script; because as is in the question it is matching the comment //asserts not the assert directly and it returns a wrong script. So I change the condition to substring(//asserts) to get a correct script.

Also since you don't show how are your asserts I assume a simple json for the sample but in your code you have to change this:

binding.setProperty('jsonSlurper', new JsonSlurper().parseText('{"field":"value", "otherField" : "secondValue"}') )

for this instead:

binding.setProperty('jsonSlurper', new JsonSlurper().parseText(resp.data) )

Hope it helps,