ahjashish
ahjashish

Reputation: 583

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

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

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

This approach was decided because there are already thousands of test cases written in SOAP UI and we want to leverage the same and not put extra effort in re-writing the test data.

While parsing the xml we can easily get the assertions from the xml in a variable as a string or a GPathResult to be more specific.

What I am not able to figure out is how to get that 'assertions string' to run as an 'assert script' on the response received from 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.someValue == expectedValue
assert jsonSlurper.someValue.someOtherValue == expectedOtherValue
assert jsonSlurper...

Upvotes: 0

Views: 795

Answers (1)

albciff
albciff

Reputation: 18517

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,

Upvotes: 0

Related Questions