Skip to content

Instantly share code, notes, and snippets.

@infomaven
Last active June 17, 2024 06:44
Show Gist options
  • Select an option

  • Save infomaven/6f8395dc1ba6ebd2178aea2a6416730a to your computer and use it in GitHub Desktop.

Select an option

Save infomaven/6f8395dc1ba6ebd2178aea2a6416730a to your computer and use it in GitHub Desktop.
SoapUI OSS - Groovy Scripting

Groovy Script Cheat Sheet

SoapUI Groovy has built-in variables that can be used to access the SoapUI object model programmatically. For each location inside the Project structure, the SoapUI Groovy console will advise which built-in variables are accessible from that location.

log // use to print things to console context // holds data about the current TestSuite testRunner // provides a reference to the project, test suite or test case object messageExchange // for scripted Assertions only. Captures the TestStep results

SoapUI Object Model Documentation

There are 3 ways that Groovy can be used in SoapUI --

  1. Groovy TestStep
  2. Script Assertion
  3. Setup | Teardown (for Project, TestSuite or TestCase)

Groovy TestStep

Groovy TestSteps are a blank slate and can be scripted to perform any task offered by regular SoapUI TestSteps in the gui.

The most common usages for Groovy TestSteps in SoapUI Open Source are

  • Read data from a file (in ReadyAPI, this is the DataSource TestStep)
  • Write data to a file (in ReadyAPI, this is the DataSink TestStep)
  • Loop through a file and use each row of data to run a TestCase (DataLooper in ReadyAPI)
  • Perform custom transformations between requests
  • connect to databases
  • Transfer data between different SoapUI components

Groovy TestSteps can also be used for utility tasks, such as creating a report from the previous test run. In this case, the TestSteps would be placed into a "Library" TestSuite and called as part of the teardown process for an active TestSuite.

Sample - Create DataSource & DataLoop with Groovy

Add external jar to SoapUI classpath

Generate random usernames for TestCase Properties

Groovy Code Snippets

  1. Using built-in Log variable

log.info(“Any Text message ” + anyVariable)

  1. Using built-in Context variable
def myVar = context.expand( ‘${#TestCase#SourceTestStep}’) //will expand TestCase property value into the new variable
context.testCase  // returns the current testCase system handle
  // ex. Fri May 31 17:45:11 PDT 2024:INFO:com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase@b864de4

  1. Using built-in TestRunner variable
testRunner.testCase.getTestStepByName(“TestStepName”)
    testRunner.testCase // return the handle to current testCase
    testRunner.testCase.testSuite.project.testSuites[“My_TestSuite”]
  1. Using built-in MessageExchange variable (for assertions only)
messageExchange.getEndpoint() //endpoint to the selected teststep
   messageExchange.getTimestamp()    //timestamp
   messageExchange.getTimeTaken()    //time taken to process the request/response
  1. Using Project, TestSuite, TestCase, TestStep methods
  • Access to lower level object (such as test steps) must be done through the hierarchy
  • project > test suite > test case > test step
def project = testRunner.testCase.testSuite.project
    def project = context.testCase.testSuite.project

    def myTestSuite = project.getTestSuiteAt(IndexNumber)
    def myTestSuite = project.getTestSuiteByName(“Name of the TestSuite”)

    def myTestCase = myTestSuite.getTestCaseAt(IndexNumber)
    def myTestCase = myTestSuite.getTestCaseByName(“Name of the TestCase”)

    def myTestStep = myTestCase.getTestStepAt(IndexNumber)
    def myTestStep = myTestCase.getTestStepByName(“Name of the TestStep”)
  1. RawRequest & RawResponse

    messageExchange.getRequestContentAsXml.toString()
    messageExchange.getResponseContentAsXml.toString()
    
  2. groovyUtils & XmlHolder

def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
   def holder = groovyUtils.getXmlHolder ("Assert_Script#Response")
  1. Converting String into Integer & Integer into String using groovy
anyStringVar = anyIntegerVar.toString()
  anyIntegerVar = anyStringVar.toInteger()
  1. Reading & Writing custom property with Groovy
  • get is a normal read only
  • set is like an upsert. If the Property did not previously exist, it will create a new one on the fly
def userIdInStep = testRunner.testCase.getTestStepByName( “UserDefinedProperty” )
   def userIdStr = userIdInStep.getPropertyValue( “myPropertyName” );
   
   // the `set` method will create and assign value if the Property did not already exist 
   userIdInStep.setPropertyValue(“newPropertyName”, “StringValueAsInput”)

10.Get or set Properties at any level

  • as mentioned above, set will also create a property if it did not already exist

SoapUI Docs

// Get a test case property
def testCaseProperty = testRunner.testCase.getPropertyValue("MyProp")
// Get a test suite property
def testSuiteProperty = testRunner.testCase.testSuite.getPropertyValue( "MyProp" )
// Get a project property
def projectProperty = testRunner.testCase.testSuite.project.getPropertyValue( "MyProp" )
// Get a global property
def globalProperty = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( "MyProp" )

// Set a test case property
testRunner.testCase.setPropertyValue( "MyProp", someValue )
// Set a test suite property
testRunner.testCase.testSuite.setPropertyValue( "MyProp", someValue )
// Set a project property
testRunner.testCase.testSuite.project.setPropertyValue( "MyProp", someValue ) 
// Set a global property
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( "MyProp", someValue )
  1. Configure TestStep request Endpoint
testRunner.testCase.getTestStepByName("dd").getHttpRequest().setEndpoint("http://cd-diudara:8280/services/linkedinFollowCompanyPage?wsdl");
def end = testRunner.testCase.getTestStepByName("dd").getHttpRequest().getEndpoint();
log.info end;
  1. Generate unique Username each time a Request is sent

a. Create a TestStep Property named Username.

b. Set Username Property value to a Property Expansion containing a Groovy random number function. Loginn${=String.valueOf(Math.random()).substring( 0, 5 )} c. Use the Property Expansion in the Request Payload for the <username> </username> element

Run SoapUI things with Groovy

Run a Test Case Located in Another Project

The following code demonstrates how you can run a test step from another project of your choice using the built-in scripting objects of SoapUI:

// Replace the project, test suite, case and step names with those you need

// Connect to the test step in another project def prj = testRunner.testCase.testSuite.project.workspace.getProjectByName("ProjectName") tCase = prj.testSuites['TestSuiteName'].testCases['TestCaseName'] tStep = tCase.getTestStepByName("TestStepName")

// Call the test runner and check if it can run the specified step def runner = tStep.run(testRunner, context) log.info ("runner status ....... : " + runner.hasResponse())

More Groovy Test Run Examples

Here

Setup and Teardown

SoapUI Set up and Teardown - Docs

Get Assertions from Test run - for example, capture results from all failed test assertions

Call Slack api

See SoapUI Docs, Section 9

Control a Mock Service

Get TestData from file

Load Properties from File to TestCase

SoapUI Groovy Code Repositories

nmrao - a SoapUI OSS Project Champion

Smartbear Team SoapUI Groovy examples on Github

SoapUI Tutorials

Run SoapUI Project, TestSuite, TestCase or Request with Groovy

Credits & References

Groovy TestStep

// Groovy - run request from same TestCase

 def status = testRunner.runTestStepByName("TestStepName")
 def result = status.getStatus().toString();
 log.info ("   ---- "+result)

// Groovy - run request from another TestCase or TestSuite

project = testRunner.testCase.testSuite.project ;
tcase = project.testSuites["TestSuiteName"].testCases["TestCaseName"] ; 
tstep = tcase.getTestStepByName("TestStepName");
def status = tstep.run(testRunner, context)
def result = status.getStatus().toString();
log.info ("   ----   "+result)

// groovy code to run test case

def tCase = testRunner.testCase.testSuite.testCases["TestCaseName"]
runner = tCase.run(new com.eviware.soapui.support.types.StringToObjectMap(), false);

// groovy code to loop test cases in a test suite

 def testCases = context.testCase.testSuite.getTestCaseList() 
 testCases.each{
 log.info(it.name)
 }

// Run TestSuite

def suite = context.testCase.testSuite.project.testSuites["TestSuiteName"]
suite.run(null,false)
// null can be replaced with : new com.eviware.soapui.support.types.StringToObjectMap()
log.info ("   ===   "+suite.getName().toString()+" - Executed successfully")

// Run a Project from a TestStep

def projectName=testRunner.getTestCase().getTestSuite().getProject().getWorkspace().getProjectByName("REST Project 1")
projectName.run(null,true)
//projectName.run(new com.eviware.soapui.support.types.StringToObjectMap(), false)

TestStep Chaining

TestStep Chaining is done when you need to pass values from one SoapUI component to another component.

For any TestCase containing more than one ApI endpoint, you will need to use it. Each TestStep Request will have a system property called "Request" and "Response" that you can access as Properties.

In addition to System Properties, you can define Custom Properties for most SoapUI components at any level of the SoapUI hierarchy.

You will always be able to view both types of Properties in the lower left corner of main SoapUI window.

There are 2 ways to do TestStep Chaining

  1. In the GUI.
  2. With Groovy Script

In the GUI

  1. Add Properties to the TestCase to capture the values that will be passed
  2. Add TestStep request that will produce the value. This is the source for the Property Tranfer.
  3. Add the TestStep request that will receive the value, taking note of the field name requiring the data. This is the target for the Property Transfer.
  4. Add a Property Transfer step between the 2 TestSteps
  5. Run the first TestSTep (the one created in #2). Examine the output and craft a query expression that isolates/extracts the value from this response. (this will require Jsonpath or XmlPath, depending on the payload's format).

    There are free tools available to help with constructing the query - jsonPath Finder - xpath tester

  6. Open editor for the Property Transfer TestStep and configure it as follows =>
    • Set first TestStep, "Response" Property as "source". Paste the query expression below
    • Set the second TestStep "Request" Property as the"target". Paste the query expression below
    • Use green Transfer command to test the expression. It will let you know if the queries were succesful.

The Property Transfer can be used to access Properties from global, project, test suite, test case or teststep.request level

Using Groovy TestStep

A Groovy TestStep has access to the testRunner built-in variable.

The testRunner variable has access to any location within the Project hierarchy (Global, Project, any TestSuite, any TestCase, any TestStep Request).

  • setup The Groovy TestStep relies on there being a source and target TestStep Request. Examine both TestSteps to see what the output and input look like.

  • Groovy code implementation

  1. Add Groovy TestStep after the first TestStep
  2. Define a local variable to capture the Response (a system property) from the first TestStep Request
  3. Use JsonSlurper or XmlSlurper class to parse the Response and extract desired value(s)
  4. Save the values as local variables
  5. Get a local reference to the second TestStep from testRunner
  6. Use the local variables to set Properties for the target TestStep in the appropriate location for that request
    • query string
    • payload
    • resource path
    • request header

Groovy example - Global Property transfer

/* task: Retrieve a global Property and pass the value to a 2 different TestCases */

// save global property as local variable
def globalPropertyValue = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( "MyProp" )

// use testRunner to access current TestCase and set a custom Property 
testRunner.testCase.setPropertyValue( "MyLocalProp", globalPropertyValue )

// use testRunner to navigate to TestCase of a different TestSuite  
def differentTestSuite = testRunner.testCase.testSuite
def anotherTestCase = differentTestSuite.getTestCaseByName(“Some other TestCase”)
anotherTestCase.setPropertyValue( "MyLocalProp", globalPropertyValue )

See Groovy Snippets for more examples using Groovy script to access Properties.

Groovy XML example

An example follows which uses a SOAP service named "Calculator Web Service"

Soap Service definition - https://ecs.syr.edu/faculty/fawcett/Handouts/cse775/code/calcWebService/Calc.asmx

/* Goal: Capture the xml "response" property belonging to a TestStep, transform its format and use it to set a Custom Property */ 
// Capture the response
def response = 
testRunner.testCase.getTestStepByName('Add').getPropertyValue("Response")

// transform the value to string
def object = new XmlSlurper().parseText(response)
def value = object.text()
log.info '   value is : '+value

// set custom Property in current TestCase using that variable
testRunner.testCase.getTestStepByName('Add').setPropertyValue('additionResult', value)

// do math with the Property value. Since it was stored as a string, it must be converted to a number
def intValue = value as Integer
def result = 100 - intValue
log.info ' result is : '+ result

The same kind of operations can be done for Json responses with the JsonSlurper class.

References

SoapUI Docs - Property Transfer

Groovy-lang Working with Json

Groovy-lang Working with Xml

Learn Groovy

Official Documentation

Groovy-Language Site

Groovy Docs - Working with Json

Groovy Docs - Working with XML

XPath Assertion

Groovy Docs - Input/Output

Smartbear Groovy TestStep

SoapUI website - Groovy vs JavaScript

SoapUI website - Object Model

Community

SoapUI Open Source Community

Stack Overflow

Ministry of Testing

Tutorials, Blogs and Videos

// Video - In Dec 2019, theSmartbear dev team did a 2 part presentation featuring Groovy and LoadUI. Although it is an older version of the product, many of these features will work with the current Open Source version (5.7.2). If you want to level up your understanding of Groovy scripting, these videos will do it quickly. Use the Chapter navigation feature to access specific topics.

Let's Get Groovy Webinar - with SoapUI and LoadUI

Groovy Webinar 2: Let's Get Groovier with LoadUI and SoapUI

Supporting code samples

10 Groovy Scripts to have under your fingers

Advanced Scripting Tutorial

You Tube Automation Step by Step Playlist

  • Provides an excellent series on use of SoapUI features. All tasks are explained using both the SoapUI gui and Groovy scripting approaches and are indexed for fast access.

Blog - StudentsApp

  • Use Groovy scripting to build an end-to-end SoapUI test from an undocumented NodeJS rest api

Groovy Script Assertions

Groovy Assertions can be implemented using any features of groovy-lang in combination with built-in SoapUI variables.

The main variable used is messageExchange, which contains details about the current TestCase.

The sky is the limit, but a few starter expressions are included below.

When Groovy Script is used for Assertions, the scripts will not be visible at Project level. You would have to locate the TestStep assertion editor where the Groovy script was selected. The sequence would be something like this -

  1. In SoapUI, navigate to the TestStep node and double-click

    Editor window opens

  2. Look in lower left corner for Assertions tab.

    Existing assertions will be listed

  3. Select the Assertion and click gear ison (settings)

    Groovy console/script editor opens

Common Patterns

Asserting XML Responses

In SoapUI, you can use the provided XmlHolder class or import the Groovy XmlSlurper class to parse xml payloads. Examples are provided for each approach.

Task: Check for a string value (aka "token") in Response

  1. Capture the response as xml (using XmlHolder or XmlSlurper)
  2. Convert captured xml to string
  3. Use Groovy assert to check for presence or absence of a token in the string

using XmlHolder

https://www.soapui.org/docs/scripting-and-properties/tips-tricks/#0-1-how-to-get-and-set-properties-from-groovy:~:text=Working%20With%20XML-,4.1%C2%A0Iterate%20Nodes,-Use%20the%20GroovyUtils

import com.eviware.soapui.support.XmlHolder
// collect the response
def holder = new XmlHolder( messageExchange.responseContentAsXml )
def responseXml = holder.getPrettyXml()
// use to check for a token. If the xml was nested, you would need to create an XPath expression to navigate to it
assert responseXml.contains('Richard E. Silverman')
// or.....use to check for absence of a token
assert !responseXml.contains('Richard E. Silverman')

using XmlSlurper

  • XmlSlurper enables you to navigate the xml using dotted notation (GPath)instead of Xpath expressions

https://groovy-lang.org/processing-xml.html#_xmlparser_and_xmlslurper

def response = new XmlSlurper().parseText(messageExchange.responseContentAsXml)
def authorResult = response.value.books.book[0].author

assert authorResult.text() == 'Miguel de Cervantes'

JSON Response

Scripted Assertion Tutorial. YouTube Automation Step by Step channel

//get json response

import groovy.json.JsonSlurper
def responseMessage = messageExchange.response.responseContent
def json = new JsonSlurper().parseText(responseMessage)

//assert node values

log.info json.name
assert json.capital.toString() != null
assert json.name.toString() == "[Taiwan]"

Assert SLA with Groovy

Assert Security test result with Groovy

More Resources

https://www.soapui.org/docs/functional-testing/validating-messages/using-script-assertions/

Sample Project using Assertion scripted with Groovy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment