We have a functional test where we use a SOAP Request to start the processing of a couple files based on a URL in the request. For a negative test (all corrupt files) we got a batch of 500 files. So to prevent a lot of copy/paste work in my SOAP Request I wanted to generate the request dynamically. I did this before, couldn’t find/remember my own example so eventually when I got it working decided to share and store it here.
First some housekeeping
I always do some housekeeping in the init groovy step of my tests to generate an unique id (for correlation, etc etc) and more.
//Generate unique id - sequence def v_sequence = new Date().time.toString() // testRunner.testCase.setPropertyValue("sequence", v_sequence) testRunner.testCase.testSuite.project.setPropertyValue("v_sequence", v_sequence) // empty some variables testRunner.testCase.testSuite.project.setPropertyValue("XML", "") testRunner.testCase.testSuite.project.setPropertyValue("teller", "1")
Then the basic dataloop
Using an external datasource is the way to go if we want to load data. In the example I only use 1 field (url) in a text file with 500 lines:
The DataSource Loop function makes it possible to go back to the Groovy script “Generate XML Request” to build the request line by line.
The Groovy magic
Here is the groovy script that holds the logic. For each url in the dataloop we create an Document XML complex element which we add to the list of
import groovy.xml.StreamingMarkupBuilder import groovy.xml.XmlUtil import groovy.util.XmlSlurper def sequence = context.expand( '${#Project#v_sequence}' ) def url = context.expand( '${DataSource#url}' ) def datumtijd = new Date().format("yyyy-MM-dd'T'HH:mm:ss") def teller = context.expand( '${#Project#teller}' ) log.info('sequence = ' + sequence) log.info('url = ' + url) def filename = url.split('/').last() log.info('filename = ' + filename) // Define all your namespaces here // def nameSpacesMap = [soapenv: 'http://schemas.xmlsoap.org/soap/envelope/',ns: 'nl.rubix.ohmy',] def builder = new StreamingMarkupBuilder() builder.encoding ='utf-8' def xmlDocument = builder.bind { // namespaces << nameSpacesMap // use it like ns.element Document { Id('DOC.' + sequence + '.' + teller); Name(filename); Date(datumtijd); Url(url); } Document } // XML buildup to get rid of irritating XML version string which probably can be done much nicer def v_document = XmlUtil.serialize(xmlDocument); v_document = v_document.substring(39) log.info("XML = " + v_document); def origineelXML = context.expand( '${#Project#XML}' ) origineelXML = origineelXML + v_document testRunner.testCase.testSuite.project.setPropertyValue("XML", origineelXML) // increase counter teller = teller.toInteger() + 1 testRunner.testCase.testSuite.project.setPropertyValue("teller", teller.toString())
The SOAP Request
Now we have a variable on project level which stores the complete list of documents, which we can just use as normal in the request like this:
<soap:Body> <ns1:Request> <Documents>${#Project#XML}</Documents> </ns1:Request> </soap:Body>