Contributions
Re: Trying to retrieve a property based on the value of another property in the Properties test step
Hello, this little script should do what you described. 1) It goes over every Serial Number in PropertyStep2 and checks if there is an appropriate Count entry, e.g. Serial Number 5 should have Count 5 etc.. If a Count entry is missing it will create one and set it to 0. 2) It will iterate over every Serial Number in PropertyStep1 and increase the Count variable in PropertyStep2. If a Serial Number cannot be found, in PropertyStep2, it will create the appropriate Serial Number entry and also create the Count entry. Script: def teststepa = context.testCase.getTestStepByName('Properties.A') def teststepb = context.testCase.getTestStepByName('Properties.B') def propertiesa = teststepa.getProperties() def propertiesb = teststepb.getProperties() // init, with value 0, or add properties named Count if necessary propertiesb.findAll{it.getKey().contains("Serial")}.each { def num = it.getKey().replace('Serial', '').replace('Number', '').trim() if(propertiesb.keySet().contains('Count ' + num)) { def val = (propertiesb['Count ' + num].getValue()) if(val == null || val.trim().isEmpty()) { teststepb.setPropertyValue('Count ' + num, '0') } } else { teststepb.setPropertyValue('Count ' + num, '0') } } //only needed if we miss, somehow, the appropriate Serial Number entry in properties B def cnt = 1 // iterate all serial number properties, in properties A, and increment count in properties B propertiesa.findAll{it.getKey().contains("Serial")}.each { pa -> def key = propertiesb.find { it.getValue().getValue() == pa.getValue().getValue() }?.getKey() if(key == null) { while(propertiesb.keySet().contains('Count ' + cnt) || propertiesb.keySet().contains('Serial Number ' + cnt)) { cnt++ } teststepb.setPropertyValue('Serial Number ' + cnt, pa.getValue().getValue()) teststepb.setPropertyValue('Count ' + cnt, '1') } else { def num = key.replace('Serial', '').replace('Number', '').trim() def val = 0 //just so that we do NOT run into invalid entries try { val = Integer.valueOf(propertiesb.find { it.getKey() == 'Count ' + num }.getValue().getValue()) } catch(Exception e) { val = 0 } teststepb.setPropertyValue('Count ' + num, (++val).toString()) } } log.info('done') TestSuite setup: Test run, before script is run: Test run, after script is run:1.6KViews0likes0CommentsRe: Verification of data having page number
Hello, since there is not a lot of information, e.g. about the response structure, I went and created a solution for the open library API, this here:https://openlibrary.org/developers/api If we search forhttp://openlibrary.org/search.json?q=hobbit&page=1we get a response in this form: { "numFound": 287, "start": 0, "docs": [ { "has_fulltext": false, "title": "Hobbit", ... }, { "has_fulltext": false, "title": "Hobbit Virtues", ... }]... } So "start" represents the current page/offset, "numFound" the total amount, "docs/title" is the value we want to grab. The project looks like this: The script in "script" looks like this: import com.eviware.soapui.support.XmlHolder import net.sf.* import net.sf.json.* import net.sf.json.groovy.* // here is a list of unique entries we expect to find // we left out almost all titles on purpose def uniqueTitles = ["Hobbit", "The Hobbit", "Untangling Tolkien"] def missedTitles = [] // a list of titles we do not have in our uniqueTitles list, e.g. should include "Der Hobbit" or "El Hobbit" etc. //since we did NOT fire any requests till now, everything is set to 0 def numFound = 0 def start = -1 // set to -1 since groovy has no do .. while, at least not in the current version used here? def docsFound = 0 def pageCount = 1 //page count starts with 1 NOT 0 def request = context.testCase.testSuite.getTestCaseByName('request').getTestStepByName('request') def params = request.getHttpRequest().getParams() params.getProperty('q').value = 'hobbit' // search for hobbit, we should find around 290 entries params.getProperty('page').value = pageCount // start with first page //request pages until we found every entry while((start + docsFound) < numFound) { //request page x and read response request.run(null, context) def response = request.testRequest.response.contentAsString def jsonSlurper = new JsonSlurper().parseText(response) //get book titles def titles = jsonSlurper.docs.collect{ it.title} titles.removeAll(uniqueTitles) if(!titles.isEmpty()) { missedTitles.addAll(titles) } //get all necessary params to check if we still have to request further entities numFound = Integer.valueOf(jsonSlurper.numFound) start = Integer.valueOf(jsonSlurper.start) docsFound = Integer.valueOf(jsonSlurper.docs.size()) params.getProperty('page').value = ++pageCount } //all titles we defined at the start log.info "${uniqueTitles.size()}: unique titles: ${uniqueTitles}" //all titles that we found but were NOT present in uniqueTitles log.info "${missedTitles.size()}: missed titles: ${missedTitles}" log.info("done") The output, at the end, after the script has run, should look something like this: 3: unique titles: [Hobbit, The Hobbit, Untangling Hobbit] 287: missed titles: [Hobbit Sketchbook, Hobbit Virtues, Hobbit lessons,... I added the project. EDIT Forgot to mention, now you can go over uniqueTitles and missedTitles to compare the entries and do further checks/corrections depending on what exactly you need.802Views2likes0CommentsRe: Contains Assert to match Regex in JSON Response
Hi, add the following JSONPath Expression: $.data[?(@.ratu_desc=='Total Canada')].ratu_desc and the Expected Result should be set to: [Total Canada] Then it does not matter where "Total Canada" is found, as long as the structure does not change. You can read more about this here: https://support.smartbear.com/readyapi/docs/testing/assertions/reference/property/json-match.html1.5KViews2likes0CommentsRe: How to add nodes for soapUI request,useing groovy?
Hi, maybe this will help you to get build/append your requests. Since I do not know where you get the data from and how it is provided (represented in the code) I will assume a list of maps, the map contains the CD information. //the request body with no CDs def reqBody = """<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"> <soap:Header> <m:Trans xmlns:m="https://www.w3schools.com/transaction/" soap:actor="https://www.w3schools.com/code/">234</m:Trans> </soap:Header> <soap:Body> <CATALOG/> </soap:Body> </soap:Envelope>""" //for our test lets use a list of maps, each map contains one CD def cds = [ [ "TITLE": "Empire Burlesque", "ARTIST": "Bob Dylan", "PRICE": "10.90"], [ "TITLE": "Hide your heart", "ARTIST": "Bonnie Tyler", "PRICE": "9.90"], [ "TITLE": "Greatest Hits", "ARTIST": "Dolly Parton", "PRICE": "9.90"], [ "TITLE": "Still got the blues", "ARTIST": "Gary Moore", "PRICE": "10.20"] ] //read in the request body and find the catalog node def root = new XmlParser().parseText( reqBody ) //<Envelope> def catalog = root.'**'.find { it.name().toString().equalsIgnoreCase("catalog") } //find catalog //now add all CDs for(cd in cds) { //create CD node Node cdNode = new Node(catalog, "CD") //add information to CD node for(key in ["TITLE", "ARTIST", "PRICE"]) { cdNode.appendNode(key, cd[key]) } } //check result till here log.info(groovy.xml.XmlUtil.serialize(root)) //add even more CDs def moreCDs = [ [ "TITLE": "Greatest Hits Vol.1", "ARTIST": "Various Artists", "PRICE": "14.95"], [ "TITLE": "Greatest Hits Vol.2", "ARTIST": "Various Artists", "PRICE": "17.95"] ] // add even more CDs for(cd in moreCDs) { //create CD node Node cdNode = new Node(catalog, "CD") //add information to CD node for(key in ["TITLE", "ARTIST", "PRICE"]) { cdNode.appendNode(key, cd[key]) } } //convert to text def requestXML = groovy.xml.XmlUtil.serialize(root) //check result log.info(requestXML) log.info("done") I used this to lookup a few examples of how to interact with an XML using XMLParser (didn't really (often) use it before): (documentation) http://docs.groovy-lang.org/latest/html/api/groovy/util/Node.html (some examples of how to use them) https://www.codota.com/web/assistant/code/rs/5c6574441095a5000151d7bf#L241 We started with: <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"> <soap:Header> <m:Trans xmlns:m="https://www.w3schools.com/transaction/" soap:actor="https://www.w3schools.com/code/">234</m:Trans> </soap:Header> <soap:Body> <CATALOG/> </soap:Body> </soap:Envelope> The result, after we run the code, looks like this: <?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"> <soap:Header> <m:Trans xmlns:m="https://www.w3schools.com/transaction/" soap:actor="https://www.w3schools.com/code/">234</m:Trans> </soap:Header> <soap:Body> <CATALOG> <CD> <TITLE>Empire Burlesque</TITLE> <ARTIST>Bob Dylan</ARTIST> <PRICE>10.90</PRICE> </CD> <CD> <TITLE>Hide your heart</TITLE> <ARTIST>Bonnie Tyler</ARTIST> <PRICE>9.90</PRICE> </CD> <CD> <TITLE>Greatest Hits</TITLE> <ARTIST>Dolly Parton</ARTIST> <PRICE>9.90</PRICE> </CD> <CD> <TITLE>Still got the blues</TITLE> <ARTIST>Gary Moore</ARTIST> <PRICE>10.20</PRICE> </CD> <CD> <TITLE>Greatest Hits Vol.1</TITLE> <ARTIST>Various Artists</ARTIST> <PRICE>14.95</PRICE> </CD> <CD> <TITLE>Greatest Hits Vol.2</TITLE> <ARTIST>Various Artists</ARTIST> <PRICE>17.95</PRICE> </CD> </CATALOG> </soap:Body> </soap:Envelope>1.2KViews1like0CommentsRe: In SoapUI how to create multiple REST Requests via groovy script?
Hi, so I usedhttp://petstore.swagger.ioto create a new rest project (don't have anything else to test against), be sure to change the GET request to a POST request, otherwise you will be unable to add anything to the request body. The project looked like this (note the [POST] Swagger.json 1, before it was [GET]): Add the following script to the groovy script test step, change <path> and <url> to what you need. import com.eviware.soapui.config.TestStepConfig; import com.eviware.soapui.impl.wsdl.teststeps.registry.RestRequestStepFactory; import com.eviware.soapui.impl.rest.RestRequest; import com.eviware.soapui.impl.rest.RestResource; import com.eviware.soapui.impl.rest.RestService; log.info('start') // the test case where we want to add stuff to def testCases = context.testCase.testSuite.project.getTestSuiteByName('testSuite').getTestCaseByName('testCases') // see also here: https://community.smartbear.com/t5/SoapUI-Open-Source/How-do-I-automatically-insert-a-REST-test-step-into-a-SoapUI/m-p/102437#M17957 // the rest template, first he interface, we only have 1 so index 0 def iface = context.testCase.testSuite.project.getInterfaceList()[0]; // get the operation, again we only have 1 so 0 def opr = iface.getOperationList()[0] // get the appropriate request, also only 1 available so 0 def res = opr.getRequestAt(0) // iterate over all files we want to add, txt files were used in my test new File('<path>').eachFile { file -> if(file.getName().toLowerCase().endsWith('.txt')) { def testStepName = file.getName(); //create the test step TestStepConfig testStepConfig = RestRequestStepFactory.createConfig( res, testStepName); def testStep = testCases.addTestStep(testStepConfig); // set the url testStep.getHttpRequest().setEndpoint("<url>"); // set content testStep.setPropertyValue('Request', file.text) } } log.info('done')2.8KViews1like0CommentsRe: Consuming SOAP web service dynamically in loop
Hi, you could achieve this with a bit of groovy scripting like this. Create a new project, add a test suite and then add 3 new test cases (script, getSiteList and getSiteInfo). Right-click on getSiteList and getSiteInfo and deactivate the test case. Add a Soap-Request to getSiteInfo and getSiteList, set the appropriate soap-endpoint for each. Add a groovy script to the test case "script". It should look like this now: Add the following code to the groovy script: def getSiteInfo = context.testCase.testSuite.getTestCaseByName('getSiteInfo').getTestStepByName("request") def getSiteList = context.testCase.testSuite.getTestCaseByName('getSiteList').getTestStepByName("request") //add code here to change userName, password, custNbr if necessary def userName = 'username' def password = 'pwsd' def custNbr = '288' //set userName, password, custNbr getSiteList.setPropertyValue('request', """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bil="http://billing.xyz.cc/"> <soapenv:Header/> <soapenv:Body> <bil:getSiteList> <!--userName--> <arg0>""" + userName + """</arg0> <!--password--> <arg1>""" + password + """</arg1> <!--custNbr--> <arg2>""" + custNbr + """</arg2> <!--lastModifiedDt--> <!--<arg3>?</arg3>--> </bil:getSiteList> </soapenv:Body> </soapenv:Envelope>""") // fire request getSiteList.run(null, context) // get response def root = new XmlSlurper().parseText(getSiteList.getPropertyValue('response')) // iterate over all siteIds and fire request based on the siteId root.'**'.findAll() {node -> node.name() == 'siteId'}.each { id -> getSiteInfo.setPropertyValue('request', """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bil="http://billing.xyz.cc/"> <soapenv:Header/> <soapenv:Body> <bil:getSiteInfo> <!--userName--> <arg0>""" + userName + """</arg0> <!--password--> <arg1>""" + password + """</arg1> <!--custNbr--> <arg2>""" + custNbr + """</arg2> <!--siteId--> <arg3>""" + id + """</arg3> </bil:getSiteInfo> </soapenv:Body> </soapenv:Envelope>""") //fire request for getSiteInfo getSiteInfo.run(null, context) //show result log.info getSiteInfo.getPropertyValue('response') // add more code here // ... } If you either run the project, test suite or groovy script it should first request the site list and then iterate of every siteId and request further information for each.958Views2likes0Comments