Forum Discussion

richie's avatar
richie
Community Hero
6 years ago

Struggling to parameterize an assertion value in groovy script

Hi,

 

I have a script assertion (courtesy of @nmrao) which verifies an .json response's specific attribute is the same value for repeating groups within the response.  It is as follows:

assert context.response, 'Request parameter is correct'
def json = new groovy.json.JsonSlurper().parseText(context.response)
//assert json.data.Name.every{1== it}
//OR the next line assert json.data.Name.every{context.expand('${REST Request#Name}') == it} //this is the same assertion as the previous line except I'm parameterizing the assertion's expected result value

I have a script (yet again, courtesy of nmrao) that dynamically builds a GET REST request using template/URI and query parameter values from properties set on the test case and a Properties step

 

//Script developed by Rao
//import decs import groovy.json.* import wslite.rest.* def serviceHost = context.expand ('${#Project#TestEndpoint}') //'https://whatevs.azurewebsites.net' //Below to handle template parameter, additional $ required before def getNamespaceDatasetPath = '''/api/1/${namespace}/${dataset}''' //define all template param values as shown below def binding = [namespace : context.expand( '${#TestCase#namespace}') , dataset : context.expand('${#TestCase#dataset}')] //def binding = [namespace : 'certification-nomenclature', dataset : 'certification-nomenclature'] def template = new groovy.text.SimpleTemplateEngine().createTemplate(getNamespaceDatasetPath) def queryParams = [:] //Get the properties of Property Test step context.testCase.testSteps["Properties"].properties.each { queryParams[it.key] = it.value.value } def client = new RESTClient(serviceHost) def response = client.get(path: template.make(binding) as String, accept: ContentType.JSON, query : queryParams ) assert response.statusCode == 200 log.info groovy.json.JsonOutput.prettyPrint(response.text) def object = new JsonSlurper().parseText(response.text) assert object.header.success == true

I wanted to add in the assertion (from the script assertion) into my groovy script test step - now if I copy in the script assertion making a couple of changes - the script assertion works in the groovyscript but ONLY if I use the hardcoded assertion line, rather than the parameterized line.

 

assert json.data.Name.every{1== it}  //hardcoded line
assert json.data.Name.every{context.expand('${REST Request#Name}') == it}  //parameterized line

So my attempt at the complete groovy script is as follows:

 

//Script developed by Rao
//import decs
import groovy.json.*
import wslite.rest.*

def serviceHost = context.expand ('${#Project#TestEndpoint}') //'https://whatevs.azurewebsites.net'
//Below to handle template parameter, additional $ required before
def getNamespaceDatasetPath = '''/api/1/${namespace}/${dataset}'''
//define all template param values as shown below
def binding = [namespace : context.expand( '${#TestCase#namespace}') ,  dataset : context.expand('${#TestCase#dataset}')]
//def binding = [namespace : 'certification-nomenclature', dataset : 'certification-nomenclature']

def template = new groovy.text.SimpleTemplateEngine().createTemplate(getNamespaceDatasetPath)

def queryParams = [:]
//Get the properties of Property Test step
context.testCase.testSteps["Properties"].properties.each {
	queryParams[it.key] = it.value.value
}
def client = new RESTClient(serviceHost)
def response = client.get(path: template.make(binding) as String,
					 accept: ContentType.JSON,
					 query : queryParams
					 )
assert response.statusCode == 200
log.info groovy.json.JsonOutput.prettyPrint(response.text)

def object = new JsonSlurper().parseText(response.text)

assert object.header.success == true

assert response.text, 'Request parameter is correct' //This line was context.response rather than response.text in the script assertion //def json = new groovy.json.JsonSlurper().parseText(response.text) //this line isn't needed as I already pass the response to the object variable above assert object.data.CertificateType_Name.every{'Other certificates'== it} //groovy executes and passes
//OR assert object.data.CertificateType_Name.every{context.expand('${REST Request#CertificateType_Name}') == it} //groovy executes but this assertion fails

Essentially when I comment out the hardcoded line and uncomment the parameterized line - the assertion fails.

 

I have spent the last 2 days playing with this trying to get the parameterized line working.  I have 2000 tests to create in ReadyAPI! and this is one of the final problems to my being able to parameterize a large percentage of my tests so I could just have 1 looping test case and just datasource all the requests.

 

Can anyone see what I'm missing? - I keep thinking I've spotted the problem, but I just don't know enough about groovy to spot it

 

Many thanks to all!

 

richie

2 Replies

  • nmrao's avatar
    nmrao
    Champion Level 3
    What does it show if you print

    log.info context.expand('${REST Request#CertificateType_Name}')
    log.info object.data.CertificateType_Name

    Again, it would make life easier, less number of iterations and less time if relevant data available at hand.
    • richie's avatar
      richie
      Community Hero

      Hahaha

       

      I'm sorry - I know, I know - I've been doing this for 20 years since uni (getting old now :()- you'd think I'd remember to plug in the evidence to my ticket - it's the same as raising a defect!

       

      Anyway - attached is the payload that's generated when the groovy step (entitled 'REST Request')

       

      I added in the 2 lines to the code as follows:

       

      assert object.data.CertificateType_Name.every{'Other certificates'== it} //this works fine
      //assert object.data.CertificateType_Name.every{context.expand('${REST Request#CertificateType_Name}') == it}
      
      log.info context.expand('${REST Request#CertificateType_Name}')
      log.info object.data.CertificateType_Name

      Results from the logging is as follows:

      INFO: {the generated response goes here}

      INFO:

      INFO: [Other Certificates, Other Certificates]

       

      Resultant from adding the logging - obviously the script is not finding CertificateType_Name property attached to the groovy step.

       

      Ok - I've found a way around this - because I'm using the JDBC step's script assertion to query the db first for that particular property and write it out to the Properties step - if I point the assertion back at the value written in the Properties step - the parameterized assertion works.

       

      assert object.data.CertificateType_Name.every{context.expand('${Properties#CertificateType_Name}') == it}

       

      but only for some of the tests - I think this might be a datatype issue - but I need to think about it a bit more first.

       

      nmrao - please don't bother looking at this yet - I don't want to waste your time - I might be able to spot the problem.

       

      Thanks - I appreciate the consideration! :)

       

      richie