Here comes a collection of useful scripts for you, be sure to check back often as we will be adding new ones continuously, and if you have some cool scripts to share please mail them to us so we can add it!
1. Accessing Properties, Settings and Names
1.1. Get and Set properties
Getting properties from groovy is straight-forward; all objects that contain properties have a getPropertyValue / setPropertyValue methods. The following examples are from inside a Groovy Script step:
// get properties from testCase, testSuite and project 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" ) // setting values is equally straigh forward testRunner.testCase.setPropertyValue( "MyProp", someValue ) testRunner.testCase.testSuite.setPropertyValue( "MyProp", someValue ) testRunner.testCase.testSuite.project.setPropertyValue( "MyProp", someValue ) com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( "MyProp", someValue )
From inside a Script Assertion, you have to access testCase in another way:
def testCaseProperty = messageExchange.modelItem.testStep.testCase.getPropertyValue( "MyProp" )
Have a look at the TestPropertyHolder interface for digging into the object model.
1.2. Get and Set Settings
Global preferences can be set via the SoapUI.settings property, the different tabs have corresponding Settings interfaces in the com.eviware.soapui.settings package, each interface defines constants for each settings. So for example to set the SSL Keystore and password programmatically, you could call
import com.eviware.soapui.settings.SSLSettings import com.eviware.soapui.SoapUI // set SoapUI.settings.setString( SSLSettings.KEYSTORE, pathToKeystore ) SoapUI.settings.setString( SSLSettings.KEYSTORE_PASSWORD, keystorePassword ) // get SoapUI.settings.getString( SSLSettings.KEYSTORE, "value to return if there is no such setting set" )
1.3. Project name
This is how to access the Project name from a Groovy Script TestStep:
testRunner.testCase.testSuite.project.name
(almost all items have a name property)
1.4. Conditional inline property expansion
This is how you could conditionally expand a property in a request, or similar, based on the value of a third custom property. If the selection TestCase property has the value "selection" the TestCase property myFirstXMLSnippet will be expanded, else mySecondXMLSnippet will be expanded:
${= testCase.getPropertyValue( "selection" ) == "first" ? testCase.getPropertyValue( "myFirstXMLSnippet" ) : testCase.getPropertyValue( "mySecondXMLSnippet" )}
2. DataSources and DataSinks
2.1. Implementing Groovy DataSources and DataSinks
Here's an example Groovy DataSource to get you going:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def projectPath = groovyUtils.projectPath
def folderName = projectPath + "/testData"
def row = testRunner.testCase.testSteps["DataSource"].currentRow
def allFiles = []
new File( folderName ).eachFile() { file ->
if( file.name =~ /.txt/ )
{
allFiles.add( file.name ) }
}
if ( (row + 1) <= allFiles.size )
{
// output to the TestStep property called inputData
result["inputData"] = new File( folderName + "/" + allFiles[row] ).text
}
Here's an example Groovy DataSink :
// Write the response from the "Test Request: login" TestStep to a file
def currentUser = context.expand( '${#TestCase#currentUser}' )
def response = context.expand( '${Test Request: login#Response}' )
new File( "C:/Users/eviware/" + currentUser + "_response.txt" ).write( response )
// To use another charset than the default, do this instead:
// new File( "C:/Users/eviware/" + currentUser + "_response.txt" ).write( response, "UTF-8" )
2.2. Aggregating multiple DataSource rows to the same request
One way to do this is to use a Datasource + Datasource Loop with a Groovy step between which appends the Datasource elements to a property, and then use the property after exiting the loop.
def countryCode = context.expand( '${DataSource#CountryCode}' )
def countryName = context.expand( '${DataSource#CountryName}' )
def frag = context.expand( '${Properties#XmlFragment}' )
def newPropertyValue = '${frag}${countryCode}${countryName}'
testRunner.testCase.setPropertyValue( 'XmlFragment', newPropertyValue )
Thanks to M McDonald for this one!
2.3. Randomizing DataSource rows
There is no built in support for DataSources fetching random rows in SoapUI, but this can be achieved with some scripting. Structure your TestCase like this:

The TestSteps should contain the following:
Original DataSourceA DataSource test step for the actual data that you want to randomize. Use this as you would normally.
Collect row// create list if necessary
if( context["allRows"] == null ) context["allRows"] = []
// append current row from Original Source to allRows
context["allRows"] << context.expand( '${Original Source#output}' )
Original loop
DataSource Loop that loops to Collect row (Target Step) for each row in Original Source (DataSource Step).
Shuffle collected rowsCollections.shuffle( context["allRows"] )Groovy DataSource
def row = testRunner.testCase.testSteps["Groovy DataSource"].currentRow
if ( row + 1 <= context["allRows"].size() )
{
result["randomRow"] = context["allRows"][row]
}
Groovy DataSource loop
DataSource Loop that loops to the first test step using the random data (Target Step) for each row in Groovy DataSource (DataSource Step).
3. XML nodes
3.1. Iterate nodes
A common and equally straight forward task, use the GroovyUtils class to create an XmlHolder, which you can use for a variety of XML related activities:
// create groovyUtils and XmlHolder for response of Request 1 request
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( "Request 1#Response" )
// loop item nodes in response message
for( item in holder.getNodeValues( "//item" ))
log.info "Item : [$item]"
If the desired content is namespace qualified (very likely for SOAP responses), you need to define the namespace first. Continuoing from above:
// define namespace holder.namespaces["ns"] = "http://acme.com/mynamspace" // loop item nodes in response message for( item in holder.getNodeValues( "//ns:item" )) log.info "Item : [$item]"
3.2. Count nodes
Use the GroovyUtils class to create an XmlHolder, which you can use for a variety of XML related activities:
// create groovyUtils and XmlHolder for response of Request 1 request def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context ) def holder = groovyUtils.getXmlHolder( "Request 1#Response" ) def numberOfLinksInParagraphs = holder["count(//html/body/p/a)"]
3.3. Advanced parsing and updating
Please read XML Parsing in SoapUI (by Robert Nemet).
4. Access JMS headers
The example below sets the JMS header JMSCorrelationID to "foo4711" for myTestStep.
def myTestStep = testRunner.testCase.getTestStepByName("Some JMS TestStep")
def msgID = "foo4711"
myTestStep.testRequest.jMSHeaderConfig.messageSelector = "JMSCorrelationID = '${msgID}'"
5. Change a request XML from groovy
This example sets the password inside a request SOAP message:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context ) // get XmlHolder for request message def holder = groovyUtils.getXmlHolder( "login#Request" ) // change password using XPath holder["//username"] = "test" // write updated request back to teststep holder.updateProperty() context.requestContent = holder.xml
6. Changing response before before it gets validated
For example if you want to change all 555 to 444 in all response messages, proper way is to use RequestFilter.afterRequest event handler and add script:
if( request.response == null ) return // get response content def content = context.httpResponse.responseContent // manipulate content content = content.replaceAll( "555", "444" ) // write it back context.httpResponse.responseContent = content
Now these changes will be picked up by assertions, too (read more at Custom Event Handlers).
7. Playback and MockService Control
7.1. Loop a sequence of TestSteps X times
A simple loop is easiest achieved by placing a Groovy Script TestStep after the last TestStep in the loop with the following content:
if( context.loopIndex == null ) context.loopIndex = 0 if( ++context.loopIndex < 10 ) testRunner.gotoStepByName( "Name of first TestStep in loop" )
This script first creates the loop counter in the context and then loops back until the value is 10 (think of it as a do...while loop)
7.2. Start and stop MockServices
This can come in handy both from the Project onLoad script (if you want to start your MockServices when the project is opened) or from a TestCase/TestSuite setup script (if you need the MockService running for your functional tests). Here from a TestCase setup script:
def runner = testCase.testSuite.project.mockServices["My MockService"].start() context.mockRunner = runner
The returned runner object is required to stop the MockService... so save it to the context and use it in the tearDown script:
context.mockRunner.stop()
Have a look at the WsdlMockService and the WsdlMockRunner classes for more methods and properties that might come in handy.
8. Logging results
8.1. Saving all TestStep's results into files
To save the result (request data, response data, response time, etc.) of every executed TestStep in a Project, create a Project EventHandler (Project Window > Events tab > Add new EventHandler) of type TestRunListener.afterStep with the following content:
filePath = 'c:/users/henrik/soapUI-results/' fos = new FileOutputStream( filePath + testStepResult.testStep.label + '.txt', true ) pw = new PrintWriter( fos ) testStepResult.writeTo( pw ) pw.close() fos.close()
8.2. Logging the result messages of all TestSteps in all failing TestCases
This is intended to run in a TestSuite Teardown Script.
for ( testCaseResult in runner.results )
{
testCaseName = testCaseResult.getTestCase().name
log.info testCaseName
if ( testCaseResult.getStatus().toString() == 'FAILED' )
{
log.info "$testCaseName has failed"
for ( testStepResult in testCaseResult.getResults() )
{
testStepResult.messages.each() { msg -> log.info msg }
}
}
}
Thanks to Finan for this one!
9. Determine whether a TestCase is run from the Command Line, as a LoadTest, etc.
if( com.eviware.soapui.SoapUI.isCommandLine() )
{
log.info "This code is executed by Command Line SoapUI"
}
if( context.LoadTestContext != null )
{
log.info "This code is executed from a LoadTest"
}
10. Use a JDBC Driver from inside a groovy script
If you want to do direct JDBC calls from a groovy script you first need to register the driver as follows
// register MySQL JDBC driver com.eviware.soapui.support.GroovyUtils.registerJdbcDriver( "com.mysql.jdbc.Driver" )
(note that you still have to add the actual JDBC Driver jar to the bin\ext folder)
11. Access SOAP Operations / REST Resources
This example accesses SOAP Operations in the Sample Project.
import com.eviware.soapui.impl.wsdl.WsdlInterface
myInterface = (WsdlInterface) testRunner.testCase.testSuite.project.getInterfaceByName("SampleServiceSoapBinding")
myOperation = myInterface.getOperationByName("login")
myRequest = myOperation.getRequestByName("Request 1")



