Run a test step in Script assertion SOAP UI - groovy

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);
}

Related

Access test case property from test suite tear down script

I am trying to access the test case property from test suite tear down script.
i am not able to use test runner properties.
def testSuiteProperty = testRunner.testCase.testSuite.getPropertyValue( "MyProp" )
Need to access the test case property using test case name.
It will be very helpful if some one can answer it.
To access the test Suite property, it is simply a case of this in your tear down script....
def someProp = context.expand( '${#TestSuite#someProp}' )
Now, I use the Pro version and I don't know what you're using, so I'm not sure if the next part of my answer will help.
In Setup Script, Tear Down script, Script assertions, you can 'right-click' in the code window where you type your script and there is a 'Get Data' menu item int he context menu. This allows you to select a piece of data of interest. In fact, the line of code above was generate by using the 'Get Data' context menu option.
To access a custom property for a given test case within your suite tear-down script, you need to do this...
def testCase = testSuite.testCaseList.find { p -> p.name == 'TestCase 2' }
def testProp = testCase.getProperty('testCaseProp');
log.info(testProp.value);
The syntax you are using is not correct
Try using this
def testCs = testRunner.testCase.testSuite.project.testSuites["name of testsuite"].getTestCaseByName(name)
def tcprop = testCs.getPropertyValue("NameOftestCaseProp")
We are first getting refernce of the test case and then accessing its property
or below should also work
def testcaseProp= testRunner.testCase.testSuite.project.testSuites["name of testsuite"].getTestCaseByName(name).getPropertyValue("name of property)
try whichever looks simple to you, though both are same

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,

SoapUI & Groovy - How to get properties from different TestCases using Run testCase

Sorry in advance. I am sure this is not a new question but I swear I've been looking for days and have tried several solutions but no one fits exactly what I need. I hope you guys can help me...
My problem:
I have a main script which sends bash commands to our server:
TestSuite: Tools;
TestCase: sendBashCommands;
TestStep: groovycript;
This test script is called by several test cases using "Run testCase". Each test case have a different bash command:
TestSuite: ServerInfo
TestCase: getServerVersion
Property: BashCommand="cat smt | grep Version"
TestStep: Run sendBashCommands
TestCase: getServerMessage
Property: BashCommand="cat smt | grep Message"
TestStep: Run sendBashCommands
...
On my sendBashCommands.groovyScript I have already tried the following:
//def bashCmd= context.expand( '${#BashCommand}' );
//it returns empty;
//def bashCmd= testRunner.testCase.getPropertyValue( "BashCommand" );
//it returns null;
//def bashCmd= context.getTestCase().getPropertyValue( "BashCommand" );
//it returns null;
def bashCmd = context.expand('${#TestCase#BashCommand}');
//it also returns empty;
Currently I use a solution which works with project properties but what I actually need is working with these properties on the level of the test case which is calling the sendBashCommand script. Is that possible? How could I do it?
I think you are doing it for maintenance purpose...
As per your approach, the result has to come as null or empty. Because your groovyscript cannot get the properties of other testcases directly. If you call a getProperty() Method directly, then it will refer to the current testStep's property. So the following approach could help you.
put the following code in your individual test cases, "getServerVersion" etc.
def currentProject = testRunner.testCase.testSuite.project
// the following is to store the names of the test suite and the test cases from which you want to call your main script
currentProject.setPropertyValue("TestSuiteName",testRunner.testCase.getTestSuite().getLabel().toString())
currentProject.setPropertyValue("TestCaseName", testRunner.getTestCase().getLabel().toString())
// call sendBashCommands here -> run sendBashCommands
put this code in your main groovy script (sendBashCommands.groovyscript)
def currentProject = testRunner.testCase.testSuite.project
def callingTestCase = currentProject.testSuites[currentProject.getPropertyValue("TestSuiteName")].testCases[currentProject.getPropertyValue("TestCaseName")]
def bashCmd = callingTestCase.getPropertyValue( "BashCommand" )
// to verify
log.info bashCmd
The project is common to all the test suites, so you have to use project property in any case, i.e., for your requirement :)
Enjoy :)

Clone TestStep from a Test Case to another Test Case using groovy

I use groovy script in my test suite to fill gaps in Automation. Here I need to clone a Property from one Test case to another Test Case. For Example.. Clone the Property test step from TestCase1 to TestCase2, In order to get values from that property.
I tried to get values in the property from one TC to another, But SOAPUI will not allow to do that action. we can't transfer a property value from one TC to another TC. So I go for cloning the Test step using groovy.
Your help is much appreciated.. Awaiting response from anyone..
Thanks,
Madhan
You can run TestCase2 from TestCase1 using test step "Run TestCase". Create properties that you need directly in TestCase2 so you can set them by "Property transfer" test step in TestCase1. More information about run test case here and about property transfer here.
Another way is to set properties and run TestCase programmatically. Something like this:
// get properties from testCase, testSuite or project if you need
def testCaseProperty = testRunner.testCase.getPropertyValue( "MyProp" )
def testSuiteProperty = testRunner.testCase.testSuite.getPropertyValue( "MyProp" )
def projectProperty = testRunner.testCase.testSuite.project.getPropertyValue( "MyProp" )
def globalProperty = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( "MyProp" )
//get test case from other project or from the same one
project = testRunner.getTestCase().getTestSuite().getProject().getWorkspace().getProjectByName(project_name)
testSuite = project.getTestSuiteByName(suite_name);
testCase = testSuite.getTestCaseByName(testcase_name);
//set properties if you need
testRunner.testCase.setPropertyValue(property_name, property_value);
testRunner.testCase.setPropertyValue(another_property_name, another_property_value);
// run test case
runner = testCase.run(new com.eviware.soapui.support.types.StringToObjectMap(), false);
The following example copies all of the properties from a test suite to the project that the test suite belongs in.
A similar mechanism could be used for test case properties, etc.
testSuite.getProperties().each {
testSuite.getProject().setPropertyValue(it.getKey(), testSuite.getPropertyValue(it.getKey()))
}
To copy from one test case to another (I will leave defining the test cases)
def sourceTestCase = youdefinethis
def destTestCase = youdefinethis
sourceTestCase.getProperties().each {
destTestCase.setPropertyValue(it.getKey(), sourceTestCase.getPropertyValue(it.getKey())
}

SOAPUI Groovy - Update XML request in another test case

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")

Resources