SoapUI Groovy scripting for testers

SoapUI Groovy scripting for testers

Back to Groovy for testers

SoapUI is a wonderful tool for testing API's. The open source version is sufficient if you know what you are doing.
By enhancing your tests with logic built in Groovy, you can do amazing things.
Here are some (in confusing order, I know) hints about the Groovy scripting capability inside SoapUI.

Basics
Properties
Proxy
Misc stuff

Basics

The OSS version doesn't have intellisense, but that has never stopped me before. If you want to code in an IDE other than SoapUI:
groovy.grape.Grape.grab(group:'com.smartbear.soapui', module:'soapui', version:'5.4.0')
groovy.grape.Grape.grab(group:'org.apache.commons', module:'commons-io', version:'1.3.2')
groovy.grape.Grape.grab(group:'org.apache.ivy', module:'ivy', version:'2.4.0')
groovy.grape.Grape.grab(group:'commons-cli', module:'commons-cli', version:'1.3.1')
The first lesson is, when scripting Groovy inside SoapUI, println doesn't work. You have to use log.info
You can simulate it if you want to test snippets outside of SoapUI
//overrides built-in log
class log {
    static String info(msg) {
		String smsg = msg.toString()
        println smsg;
    }
}

String msg = "Hi from the log class"
log.info msg
It can be a bit overwhelming how many different ways there are of accessing elements in SoapUI. This is how you can address test cases:
def testCase = testRunner.testCase
log.info testCase

def testCaseName = testRunner.testCase.name
log.info "testCaseName: ${testCaseName}"
And test steps:
def testStep = testCase.getTestStepAt(0)
def testStepA = testCase.getTestStepAt(0)
def testStepB = testCase.getTestStepByName("testStep1")
def testStepC = testCase.testSteps["testStep1"]
log.info testStepA
log.info testStepB
log.info testStepC
//or 
def testStep1 = testCase.getTestStepAt(0)
def testStep2 = testCase.getTestStepByName("testStep1")
def testStep3 = testCase.testSteps["testStep1"]
log.info testStep1
log.info testStep2
log.info testStep3
By using context:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
testCase = testRunner.testCase
log.info testCase

def stepNameVariable = context.expand('${#TestCase#SourceTestStep}')
log.info stepNameVariable
log.info context.testCase.name

stepNameVariable = context.expand('${#TestCase#SourceTestStep}')
log.info stepNameVariable
log.info context.testCase.name
Project name:
def projectName = testRunner.testCase.testSuite.project.name
log.info "projectName: ${projectName}"
With log, context and testRunner built-in variables many things can be accessed:
groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def projectPath = groovyUtils.projectPath
log.info "projectPath: ${projectPath}"

def projectPathFromGet = groovyUtils.getProjectPath()
log.info "projectPathFromGet: ${projectPathFromGet}"
Test step
def thisTestStep = context.getCurrentStep().getLabel()
log.info "thisTestStep: ${thisTestStep}"
//or get it from the context variable
log.info context.testCase.name
def project = context.testCase.testSuite.project
def testStep4 = project.testSuites['TestSuite 1'].testCases['TestCase 1'].testSteps['SOAP Request1']
def testStep5 = project.getTestSuiteByName('TestSuite 1').getTestCaseByName('TestCase 1').getTestStepByName('SOAP Request1')
assert testStep4 == testStep5
Calling a web service and getting the result from the response XML
/* The web service method is as follows in Java:
 *  String callMe() {
 *  	   String callMeReturn = "ping!";
 *  	   return callMeReturn;
 *  }
*/

stepNameVariable = context.expand('${#TestCase 1#SOAP Request1}')
log.info "stepNameVariable: ${stepNameVariable.value}"

def soapTestStep = testRunner.testCase.getTestStepByName("SOAP Request1").name
testRunner.runTestStepByName(soapTestStep)

def responseSOAP = context.expand('${SOAP Request1#Response}')
def responseSection = responseSOAP =~ /callMeReturn>(.*)<\/callMeReturn/
def response = responseSection[0][1]
log.info "response: ${response}"
Get a response value:
import com.eviware.soapui.support.XmlHolder
def xml = new XmlHolder(context.response)
//getting response with xpath
def responseValue = xml.getNodeValue("//*:callMeResponse/*:callMeReturn")
log.info "responseValue : ${responseValue}"
Display a dialog box
def alert = com.eviware.soapui.support.UISupport
if (response == 'ping!') {
	alert.showInfoMessage("Value is: ${response}", "Attention")
}
else {
	alert.showErrorMessage("Response doesn't match")
}
Get all SOAP calls
import com.eviware.soapui.impl.wsdl.teststeps.*

def totalTests=0
for( testCase6 in testRunner.testCase.testSuite.getTestCaseList() ) {
	log.info "testCase.getName(): ${testCase6.getName()}"
	for( testStep in testCase6.getTestStepList() ) {
		log.info "testStep.getName(): ${testStep.getName()}"
		if( testStep instanceof WsdlTestRequestStep ) {
			log.info "instance of WsdlTestRequestStep"
			if (testStep.isDisabled() == false) {
				totalTests ++
			}
		}
	}
}

log.info "There are ${totalTests} WSDL request test steps"
More working with test steps
def testStepCount = testRunner.testCase.getTestStepCount()
log.info "There are ${testStepCount} test steps"

def testStep6 = testRunner.testCase.getTestStepAt(0)
def testStep7 = testRunner.testCase.getTestStepByName("Groovy Script")
def testStep8 = testRunner.testCase.testSteps["callMe"]
log.info "testStep1.name: ${testStep6.name}"
log.info "testStep2: ${testStep7.name}"
log.info "testStep3: ${testStep8.name}"

log.info "context.testCase.name: ${context.testCase.name}"

Properties

Setting properties
testRunner.testCase.setPropertyValue("CasePropName", "PropValue1")
testRunner.testCase.testSuite.setPropertyValue("SuitePropName", "PropValue2")
testRunner.testCase.testSuite.project.setPropertyValue("ProjectPropName", "PropValue3")
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue("GlobalPropName", "PropValue4")
Getting properties
assert testRunner.testCase.getPropertyValue("CasePropName") == "PropValue1"
assert testRunner.testCase.testSuite.getPropertyValue("SuitePropName") == "PropValue2"
assert testRunner.testCase.testSuite.project.getPropertyValue("ProjectPropName") == "PropValue3"
assert com.eviware.soapui.SoapUI.globalProperties.getPropertyValue("GlobalPropName") == "PropValue4"

String[] props = context.getPropertyNames()
log.info "All Properties: ${props.join(', ')}"
Delete properties
testRunner.testCase.removeProperty("CasePropName")
testRunner.testCase.testSuite.removeProperty("SuitePropName")
testRunner.testCase.testSuite.project.removeProperty("ProjectPropName")
com.eviware.soapui.SoapUI.globalProperties.removeProperty("GlobalPropName")

Proxy settings

import com.eviware.soapui.SoapUI
import com.eviware.soapui.settings.ProxySettings
SoapUI.settings.setString(ProxySettings.ENABLE_PROXY, "false" )
SoapUI.saveSettings()
SoapUI.updateProxyFromSettings()

Misc

Set HTTP basic auth for all WSDL test requests in test case
import com.eviware.soapui.impl.wsdl.teststeps.*

for( testCase4 in testRunner.testCase.testSuite.getTestCaseList() ) {
	log.info("Setting HTTP basic auth for all WSDL test requests in test case ["+ testCase4.getLabel()+"]")
	for( testStep in testRunner.testCase4.getTestStepList() ) {
		if( testStep instanceof WsdlTestRequestStep ) {
			testStep.getTestRequest().setUsername(testSuite.getPropertyValue("Authorization"))
			testStep.getTestRequest().setPassword(testSuite.getPropertyValue("HeaderValue"))
		}
	}
}
Programmatically create suite, case and groovy steps
import com.eviware.soapui.impl.wsdl.teststeps.registry.GroovyScriptStepFactory
suite = context.testCase.testSuite.project.addNewTestSuite("AutomatgicallyAddedSuite")
tc = suite.addNewTestCase("AutomatgicallyAddedCase")
gs1 = tc.addTestStep( GroovyScriptStepFactory.GROOVY_TYPE, "AutomatgicallyAddedGroovyScript 1" )
gs2 = tc.addTestStep( GroovyScriptStepFactory.GROOVY_TYPE, "AutomatgicallyAddedGroovyScript 2" )
gs1.properties["script"].value = 'log.info(\'Hi from AutomatgicallyAddedGroovyScript 1\')'
//delete it - useful for teardown
testRunner.testCase.testSuite.project.removeTestSuite(testRunner.testCase.testSuite.project.getTestSuiteByName("AutomatgicallyAddedSuite"))
Programmatically create mock service
def mockService = project.addNewMockService("Automagix")
// you can add operations to the mock service, but it gets hairy
project.removeMockService(mockService)
Extract all groovy code from project file to script files
import com.eviware.soapui.impl.wsdl.teststeps.WsdlGroovyScriptTestStep
def testCases = context.testCase.testSuite.getTestCaseList()
testCases.each {
	for( testSteps in it.testStepList ) {
		if( testSteps instanceof WsdlGroovyScriptTestStep ) {
			def outfile = new File("D:/temp/${it.name}-${testSteps.name}.groovy")
				outfile.write(testSteps.getScript())
		}
	}
}

© 2003-2019 ou-ryperd.net