Hello Readers,
Greetings from TechCrooks.com. Today, we will learn about Groovy Scripting and how it can power the SOAP UI Tool, one of the leading Web Services/ API testing tools in the market.
You might be aware of various Web services testing tools like ParaSoft SOATest, SOAP Sonar, Itko LISA, etc. Smart Bear's SOAP UI Pro tool is one among the services testing tools, which has few amazing features like easier property/data transfer, running the scripts in multiple environment/servers, Data Source feature for data parametrization, etc..
SOAP UI Pro tool costs close to 350$ for each of the stand alone licences for a period of 1 year. But the beta version of the tool is free to use with a limited features. But have you ever wondered if you can get all those cool features that you have in the pro version of the tool in beta? If yes, we like your thinking. The tool allows the user to create his/her own scripts using Java/Groovy. Though not all the features can be achieved in beta, most of them can be created using the scripting support that SOAP UI beta provides for free.
"
Oh come on. Don't ask me to learn a language now." See, we read your mind. :) Need not panic. Groovy is one of the best scripting languages used to manipulate with the XMLs. You need to have basic Java Knowledge to understand the sytax and data types of the script. Yes, just the basic knowledge.
In this post, we will just see how groovy scripting can be used with SOAP UI beta 4.5.1 tool.
Below are few of the features that you can achieve using Groovy Scripts.
We are considering that you already have a little knowledge on the tool.
Features:
1)Data/Property transfers:
Say we have a scenario where we have to pass a value from the response of one method to the request of next method to continue a process.
Eg: Search for a product, and make a payment for a particular product ID from the search product response.
Below is the groovy script to achieve the same:
java.lang.Integer
java.lang.String
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context );
// create holder for Search response
def holder = groovyUtils.getXmlHolder( 'SearchProducts_XMLRequest#ResponseAsXml' );
// create a variable productID to temporarily save the value and provide a valid XPath
def productID = holder.getNodeValue( '//ShoppingSearchResponse[1]/ShoppingSearchResults[1]/Products[1]/Camera[1]/@id' );
log.info('The product ID is : ' + productID );
//Saving the value of productID in the Global properties
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( 'PropTransferSearchproductID', productID);
Now the same Global properties value will have the required product ID from the search product response.
The same can be accessed in the Payment product request-> Product Id tag. Below is the implementation:
<productID>${#Global#PropTransferSearchproductID}</productID>
Instead of doing the saving the required value on a global level, it can be saved on various other levels. We will discuss the same in the next point.
2)Assigning and Accessing the property values at various levels:
The properties can be assigned and accessed at 4 different levels in SOAP UI tool.
A)
At Global level - A property value saved at a global level can be accessed by any of projects in the Soap UI workspace.
Soap UI Global properties can be accessed from the File Menu->Preferences option->Global Properties tab.
Assigning:
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( 'PropTransferSearchproductID', productID);
Accessing:(In a XML)
<productID>${#Global#PropTransferSearchproductID}</productID>
Accessing:(In a Groovy)
def GlobalproductID = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( 'PropTransferSearchproductID');
(or)
def GlobalproductID = context.expand( '${#Global#PropTransferSearchproductID}' );
SOAP UI Global properties are mostly used to drive the endpoint or WSDL, Authentication details for Basic HTTP Authentication, DB Authentication, DB Schema name, etc.. which will be the same for the entire workspace.
B)
At Project level - A property value saved at a project level can be accessed by all the testsuites and test cases under that project.
Assigning:
testRunner.testCase.testSuite.project.setPropertyValue( 'PropTransferSearchproductID', productID);
Accessing:(In XML)
<productID>${#Project#PropTransferSearchproductID}</productID>
Accessing:(In a Groovy)
def ProjectproductID = testRunner.testCase.testSuite.project.getPropertyValue( 'PropTransferSearchproductID');
C)
At TestSuite level - A property value saved at a testsuite level can be accessed by all the testcases under the designated testsuite.
Assigning:
testRunner.testCase.testSuite.setPropertyValue( 'PropTransferSearchproductID', productID);
Accessing:(In XML)
<productID>${#TestSuite#PropTransferSearchproductID}</productID>
Accessing:(In a Groovy)
def TestSuiteproductID = testRunner.testCase.testSuite.getPropertyValue( 'PropTransferSearchproductID');
D)
At TestCase level - A property value saved at a testcase level can be accessed only by that particular test case.
Assigning:
testRunner.testCase.setPropertyValue( 'PropTransferSearchproductID', productID);
Accessing:(In XML)
<productID>${#TestCase#PropTransferSearchproductID}</productID>
Accessing:(In a Groovy)
def TestCaseproductID = testRunner.testCase.getPropertyValue( 'PropTransferSearchproductID');
SOAP UI also allows the user to add a "
Properties test step" which is similar to the testcase level property. All the Test Steps under the test case can access al the property values from a Property test step.
Assigning:
def propertyStep = testRunner.setTestCase().getTestSuite().getTestCaseByName('001_testcasename').getTestStepByName('TestStepName')
propertyStep.setPropertyValue('PropTransferSearchproductID', value);
Accessing:(In XML)
<productID>${#PropertiesStepName#PropTransferSearchproductID</productID>
Accessing:(In a Groovy)
def Value = context.expand( '${PropertiesStepName#PropTransferSearchproductID}' );
(or)
def propertyStep = testRunner.getTestCase().getTestSuite().getTestCaseByName('001_testcasename').getTestStepByName('TestStepName')
def RowStartValue = propertyStep.getPropertyValue('PropTransferSearchproductID');
3)Controlling the flow of execution:
The flow of execution can be controlled by adding a condition in groovy script and forcing the control to go to a particular script. Below is a sample script for the same,
def envvalue = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( 'environment' )
public int env = envvalue;
env = env - 48
if (env.value == 1)
{
log.info 'Execution on First Environment : Completed'
temp = '2';
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( 'environment', temp);
testRunner.gotoStepByName( 'ABC_STEP');
}
else if (env.value == 2)
{
log.info 'Execution on SecondEnvironment : Completed'
temp = '3';
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( 'environment', temp);
testRunner.gotoStepByName( 'XYZ_STEP')
}
4)Reading and manipulating the WSDL's at runtime:
The WSDL's or End point URL's can be accessed at runtime, and the same can be manipulated. Below is a sample script which tells us how to compare two WSDL URL's.
def TextInWSDL = 'Product'
def EndPointURL = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( 'EndPointURL')
log.info('EndPointURL from Global: ' + EndPointURL );
def newEndPointURL = EndPointURL.replace('.', '')
newEndPointURL = newEndPointURL.replace('http://', '')
log.info('NewEndPointURL: ' + newEndPointURL );
def StringAppend = newEndPointURL.getAt(6) + newEndPointURL.getAt(7) + newEndPointURL.getAt(8) + newEndPointURL.getAt(9)
log.info('StringAppend: ' + StringAppend);
log.info('TextInWSDL: ' + TextInWSDL + StringAppend);
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( 'PropTransferBookingIDFormat', TextInWSDL + StringAppend);
Note: For this script to work, the Endpoint URL in your SOAP UI Tool should have been parametrized like ${#Global#EndPointURL}.
5)Running the scripts in multiple environments:
Instead of creating two set of scripts to run on two Endpoint URL's (or two different servers), groovy gives a flexibility to run the same set of scripts on multiple environments.
To Achieve this, we will be making use of the SOAP UI tool
's multiple environment feature which is applicable only from SOAP UI v4.5.0 or later.
This is a 3 step process:
1)You have to set a dummy value to your enviroment:
2)You have to select the required environment:
3)You have to loop back to the next environment:
Setting a dummy value for the environment variable:
import java.lang.String;
import java.lang.Integer;
temp = '1';
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( 'environment', temp);
Selecting Environment at Run time:
def GlobalEnvironmentID = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( 'Environment');
log.info GlobalEnvironmentID
if (GlobalEnvironmentID .value == 1)
{
testRunner.testCase.testSuite.project.setActiveEnvironment('FirstEnvironment')
log.info 'Running the test on QA_STABLE Build'
}
else if (GlobalEnvironmentID .value == 2)
{
testRunner.testCase.testSuite.project.setActiveEnvironment('SecondEnvironment')
}
Looping back to the next Environment:
def envvalue = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( 'environment' )
public int env = envvalue;
env = env - 48
if (env.value == 1)
{
log.info 'Execution on FirstEnvironment : Completed'
temp = '2';
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( 'environment', temp);
testRunner.gotoStepByName( 'FIRST_TEST_STEP');
}
else if (env.value == 2)
{
log.info 'Execution on SecondEnvironment : Completed'
temp = '3';
com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( 'environment', temp);
testRunner.gotoStepByName( 'LAST_TEST_STEP')
}
6)Groovy Assertions:
SOAP UI Generic assertions cannot assess complex scenarios which include various conditions. Hence a script assertion have to be used.
To access a testcase property in a script assertion:
def testCaseProperty = messageExchange.modelItem.testStep.testCase.getPropertyValue( 'PropertyName' )
Sample Assertion Script:
//Get the XMLStepname
def XMLStepname = messageExchange.modelItem.testStep.getName()
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context );
// create holder for the response
def holder = groovyUtils.getXmlHolder( XMLStepname + '#ResponseAsXml' );
def xml = new XmlSlurper().parseText(holder.getXml())
// Find the Tag Name and attribute name
def tag= xml.depthFirst().findAll { it.name() == 'TagName' && it.@type == 'AttributeName' }
//Count the total number of tags
def PropertyName= tag.size()
log.info PropertyName
assert PropertyName == 1
Will return an assert value true or false, true if 'PropertyName = 1 and false if PropertyName = any other value'
7)Groovy Data Source loop:
A groovy data source is a custom data source to iterate or parametrize values. Below is a sample script to create a groovy data source:
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
}
We have not really implemented the groovy data source and data source loop. The above code is just an extract from the official SOAP UI site. For more information on this, please
click here.
8)Renaming a request in SOAP workspace at run time:
Below groovy script uses a .setName function to set a test step name at run time.
for( testCase in testRunner.testCase.testSuite.getTestCaseList() )
{
for( testStep in testCase.getTestStepList() )
{
String TestStepName = testStep.getLabel()
if( testCase.getLabel() == TestCaseName )
{
if (TestStepName =~ 'XML1')
{
testStep.setName('ABC')
}
else if (TestStepName =~ 'XML2')
{
testStep.setName('XYZ')
}
}
}
}
Few of the awesome cool features like controlling the flow of execution, Conditional script assertions, Switching Environment at runtime, etc. are available to the tool only through groovy scripting.
Though all these good to have features can be achieved, SOAP UI Pro always allows the user to do things in the most easiest way. To mention a few, XPATH Quert, property transfer using the property transfer environment, support for multiple environments, a datasource step with click and extract data, etc.
Thanks,
Swaminathan.B
Your feedback and comments are most welcomed.