SOAPUI Groovy - Update XML request in another test case - groovy

I am having 2 test cases in my suite.
First test case contains 1 test step with xml request.
Second test case contains 1 test step with groovy script. I want to run the 1st test case from this groovy script a number of times. Every time I want to change the input XML. I am unable to update the input XML in TestCase 1.
I have the following the code for the groovy script:
import com.eviware.soapui.support.XmlHolder
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context);
def tsuite = testRunner.testCase.testSuite
def acctInq_tstepName = tsuite.getTestCaseAt(1).getTestStepAt(0).getName()
def acctInq_requestHolder = tsuite.getTestCaseAt(1).testSteps[acctInq_tstepName].testRequest.getRequestContent()
def acctInq_req = groovyUtils.getXmlHolder("$acctInq_requestHolder")
acctInq_req["//soapenv:Envelope[1]/soapenv:Body[1]/v2:AcctInqRq[1]/ifx:DepAcctId[1]/ifx:AcctId[1]"] = "0009917812344"
acctInq_req.updateProperty()
I also tried using
tstep.setPropertyValue("request",cStr(acctInq_req))
In either case the XML is not getting updated. Please help.

Try set node value like below and check if it fixed the issue:
acctInq_req.setNodeValue("//*:ifx:AcctId[1]", "0009917812344")

Related

Transfer list between Groovy test steps (SoapUI)

I have one test case which is called (started and finished) before every run of other test cases. It is something like 'test data preparation' test case. Output from this test case is list with some elements, list looks like this:
def list = ['Login', 'Get Messages', 'Logout', etc.]
List is different on every run. I need to transfer this list from 'test data preparation' test case to other test cases. Transfer will be between two Groovy scripts.
How to transfer list between two Groovy test steps in SoapUI?
As I understand it:
You have one TestCase, which you call from every other TestCase.
I assume this is done using a "Run TestCase" teststep?
You would like to be able to pass a list of strings
As I read it, parameters go one way. From the "external testcase" and back to the calling testcase. There is no "input" from each testcase to this "external testcase"?
The Groovy Script in your "external testcase" may then generate a String result, which in turn can be converted to something like an Array or ArrayList of Strings.
This could be a string with values separated by ;
def result = ""
result += "Entry1;"
result += "Entry2;"
result += "Entry3;"
// You may want to add a line of code that removes the last ;
return result
This result will then be easily retrieved from Groovy Scripts elsewhere, by adding a few lines of code.
If the Groovy Script is placed in another TestCase, but in the same TestSuite, you may retrieve the result using:
def input = testRunner.testCase.testSuite.getTestCaseByName("Name of TestCase").getTestStepByName("Groovy Script Name").getPropertyValue("result")
If it is placed in a TestCase in a different TestSuite, you may use:
def input = testRunner.testCase.testSuite.project.getTestSuiteByName("Test Suite Name").getTestCaseByName("Test Case Name").getTestStepByName("Groovy Script Name").getPropertyValue("result")
and then loop over the input doing something like:
for (def s : input.split(";")) {
log.info s
// Do your stuff here
}
I hope that makes sense...? :)
from groovy step 1 you shall return the list:
def list = ['Login', 'Get Messages', 'Logout']
return list
from groovy step 2 you can get this returned list
def result = context.expand( '${Groovy Script 1#result}' )
list = result.tokenize('[,] ')
list.each{
log.info it
}
note that you get a string that you have to convert back to a list (tokenize).
I did this with SOAPUI pro.
Another way (ugly) would be to store the list in a custom property in groovy script 1 (using testRunner.testCase.setPropertyValue("myList",list.toString())
and to recover it in groovy step 2 (testRunner.testCase.getPropertyValue("myList")
I hope that will help
EDIT : if list elements contain spaces
this is not very clean and I hope someone will help to provide something better but you can do the following :
list = "['Login - v1', 'Get Messages - v2', 'Logout - v1']"
list = list.replace('\'','\"')
def jsonSlurper = new groovy.json.JsonSlurper()
list = jsonSlurper.parseText(list)
list.each{
log.info it
}
Alex

How can we add SOAP request Test step in a Test Case using groovy scripts

I am looking for adding a SOAP request Test step in a test case, from a different TestSuite and test case, i have already coded the part to add Groovy script for same requirement but not able to add a SOAP request test step. Any help?
following is my code:
import com.eviware.soapui.impl.wsdl.teststeps.registry.GroovyScriptStepFactory
suite = context.testCase.testSuite.project.addNewTestSuite("AutomatedTestSuite")
tc = suite.addNewTestCase("automatedTestCase")
gs = tc.addTestStep( GroovyScriptStepFactory.GROOVY_TYPE, "GroovyScript1" )
gs2 = tc.addTestStep( GroovyScriptStepFactory.GROOVY_TYPE, "GroovyScript3" )
gs.properties["script"].value = 'log.info(\'hello world\')'
You can get the another testSuite,testCase and testStep by it's name through project as follows:
def project = context.testCase.testSuite.project
def testStep = project.testSuites['TestSuiteName'].testCases['TestCaseName'].testSteps['testStepName']
Or alternatively instead of array approach using getXXXXbyName method:
def testStep = project.getTestSuiteByName('TestSuiteName').getTestCaseByName('TestCaseName').getTestStepByName('testStepName')
Then to add this testStep to your testCase you can use cloneStep(WsdlTestStep testStep, String name) method.
All together in your script:
def suite = context.testCase.testSuite.project.addNewTestSuite("AutomatedTestSuite")
def tc = suite.addNewTestCase("automatedTestCase")
// get desired testStep
def project = context.testCase.testSuite.project
def testStep = project.testSuites['TestSuiteName'].testCases['TestCaseName'].testSteps['testStepName']
// add it to your new generated testCase
tc.cloneStep(testStep,testStep.name + "_Copy")
EDIT BASED ON COMMENT
If instead of a copy of another SOAP testStep you want to create a new one, you can do it using the follow code. Take in account that to create a testStep of SOAP type more info is needed than when you create a groovy one due to the need for wsdl operation info (in the example we take the first one but if you've more than one take care of what you take).
IMO the first approach is simpler, you can copy another testStep and change the properties you want... anyway if you want to do it this way here you're:
import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestRequestStepFactory
def suite = context.testCase.testSuite.project.addNewTestSuite("AutomatedTestSuite")
def tc = suite.addNewTestCase("automatedTestCase")
// get the WSDL operation... for the example we take the first one
// however if you've more get the correct one
def operation = testRunner.testCase.testSuite.project.getInterfaceAt(0).getOperationList()[0]
// factory to create the testStepConfig
def factory = new WsdlTestRequestStepFactory()
def config = factory.createConfig(operation,'stepName')
// create the testStep
def testStep = tc.addTestStep(config)
// change the request
testStep.properties['Request'].value = '<request>someData</request>'
Hope it helps,

Run a test step in Script assertion SOAP UI

I have 5 test steps in a test case and i want to write a script assertion for a test step
Like
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def httpResponseHeaders = context.testCase.testSteps["Step1"].testRequest.response.responseHeaders
def httpStatus = httpResponseHeaders["#status#"]
def httpStatusCode = (httpStatus =~ "[1-5]\\d\\d")[0]
if (httpscode == "500")
I want to re-run the test step named as step 1
I know that testRunner class is not present in Script assertion is there a way to do it with messageExchange variable class
I saw an answer on stack overflow
`messageExchange.modelItem.testStep.testCase.getTestStepByName("Step1").run(context.getTestRunner(),context)`
I tried the code but as soon as i click run SOAP UI hangs and I have to force close the SOAP UI application
To run a test step from script assertion you may use this
import com.eviware.soapui.support.types.StringToObjectMap
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
def Runner = new WsdlTestCaseRunner(messageExchange.modelItem.testStep.testCase, new StringToObjectMap())
yourTestStep= messageExchange.modelItem.testStep.testCase.testSuite.project.testSuites["ScriptLibrary"].testCases["Library"].testSteps["Lib"]
yourTestStep.run(Runner,context)
Your code is fine, except your logic is flawed, because you encounter the error 500 for the first time and then you call the same step again and it fails again with 500 and so on. You would need to get different status, before your Java runs out of memory.
So if you want to do something like that, you have to implement some kind of counter (using TestCase, TestSuite, Project or Global property) to perform this loop only several times and then fail.
Anyway this worked for me:
def utilitiesSuite = messageExchange.modelItem.testStep.testCase
.testSuite.project.getPropertyValue('utilitiesTestSuiteName');
messageExchange.modelItem.testStep.testCase.testSuite.project
.testSuites[utilitiesSuite].testCases["Test Case utility name"]
.run(null, true);
In this case we have all "utilities" = test cases with some often needed functionality in a dedicated test suite and I wanted its name to be possible to set up on Project level, of coures the Test Suite name can be put there directly as for example "Utilities'.
Also i have tried with this:
context.getTestRunner()
As the first parameter in the methor run instead of the null, but it worked only when testing the one requirement, not when running whole test case or test suite.
I let here another example that worked for me.
It's an assertion script, which runs a testStep basing on a response node value.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context );
def holder = groovyUtils.getXmlHolder( "yourTestStep#response" );
def myValue = holder.getNodeValue( "//theNameSpace:yourNode" );
if(myValue == 'whateverYouWant'){
//com.eviware.soapui.support.UISupport.showInfoMessage(myValue);
def Runner = new com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner(
messageExchange.modelItem.testStep.testCase, new com.eviware.soapui.support.types.StringToObjectMap());
def mySteps= messageExchange.modelItem.testStep.testCase.testSuite.project.testSuites["yourTestSuite"].testCases["yourTestCase"].testSteps["yourTestStep"];
mySteps.run(Runner,context);
}

Context missing from called test case

In SoapUI I’m running a test case from a groovy script with this code:
def contextMap = new StringToObjectMap(context)
def myTestCase_1 = myTestSuite.getTestCaseByName("TestcaseName")
myTestCase_1.run(contextMap, false)
In the called test case I set some context properties in a groovy script in this way: context.setProperty(“ProperyName”,”Value”)
After the called test case has finished the created property values are missing in the context of the groovy script that has called this test case.
How can I pass back property values to a test case that called another test case?
Instead of using context if you want to share properties through different testCases in the same testSuite try to set the properties on the testSuite level which will be shared for all testCases in this testSuite. For example if you have a testSuite with two testCases: testCase 1 and testCase 2, on a groovy script from testCase 1 do:
testRunner.testCase.testSuite.setPropertyValue( "sharedVar", "someValue" )
Then to use this property from another groovy script in testCase 2 use:
def shared = testRunner.testCase.testSuite.getPropertyValue("sharedVar")
log.info shared
You can also use this testSuite property saved in the testCase 1 in the testCase 2 for example in testStep SOAP Request using: ${#TestSuite#sharedVar}
EDIT BASED ON OP COMMENT:
Since seems that the OP problem is how to get the properties from a testCase which is called from another testCase using groovy script; here is a possible work around, which consists in through the run result get the invoked testCase and then get his properties:
The first testCase which invokes the other testCase using groovy looks like:
import com.eviware.soapui.support.types.StringToObjectMap
def contextMap = new StringToObjectMap(context)
def testCase2 = testRunner.testCase.testSuite.getTestCaseByName("TestCase 2")
// get the result since is running sync
def result = testCase2.run(contextMap, false)
// from the result access the testCase and then the properties setted there
log.info result.getTestCase().getPropertyValue("varSettedOnTestCase2")
In the second testCase simply perform your logic and set the properties which will be get back from the first testCase:
testRunner.testCase.setPropertyValue("varSettedOnTestCase2","test")
Hope this helps,

Data Source loop creation using groovy script

I am trying to create a regression test suite for my project in SOAP UI 4.5(no a pro version). I have created groovy script to read request data from excel sheet. The problem which i am facing is that i am not able run test cases in loop. The test case which comes after execution of groovy script is taking the last value only. I want the testcases to run for each iteration(the functionality in SOAP UI pro is implemented using datasource loop). Please suggest some solution. I am new to groovy scripting. Here is the groovy script which i have created up till now :
import org.apache.poi.hssf.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
InputStream inp = new FileInputStream("workbook.xls");
POIFSFileSystem fs = new POIFSFileSystem(inp);
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
for (HSSFRow row : sheet) {
def rownum = row.getRowNum();
log.info rownum;
def value1 = row.getCell(0).getStringCellValue();
def value2 = row.getCell(1).getStringCellValue();
log.info value1;
log.info value2;
context.setProperty("companyid",value1)
companyid = context.expand('${companyid}')
context.setProperty("operation",value2)
operation = context.expand('${operation}')
}
Execution in soapUI is sequential and what is happening in your case is that the groovy code is executed and then soapUI executes the next step as at that time your code has gone through all the rows in the excel and the data in the properties is from the last row in excel that is why the next step is executed with data from the last row of excel.
As you are controlling the flow your tests execution using groovy, i.e., this groovy script is your driver. In this case you also need to include code to call all the steps that are part of the regression script, try the below code from soapUI forum
import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus
def testStep = .. create your teststep..
def result = testStep.run( testRunner, context )
if( result.status == TestStepStatus.OK )
{
...
}
else
{
...
}
Another thing you need to remember is once soapUI has finished executing this groovy script and hence your regression it will move to the next step in the same test case as the groovy step which you want to avoid as they have already been executed in your groovy step. To do this i can suggest two things.
Disable all the steps other than the groovy step. soapUI will skip over the disabled steps.
[Link to disable test step] (http://www.soapui.org/forum/viewtopic.php?t=126)
Second and probably my fav, move all the steps you are going to call in your groovy code to a seperate test case/test suite.
Hope this helps!

Resources