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.
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:
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:
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:
Accessing:(In a XML)
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:
Accessing:(In XML)
Accessing:(In a Groovy)
C)At TestSuite level - A property value saved at a testsuite level can be accessed by all the testcases under the designated testsuite.
Assigning:
Accessing:(In XML)
D)At TestCase level - A property value saved at a testcase level can be accessed only by that particular test case.
Assigning:
Accessing:(In XML)
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:
Accessing:(In XML)
Accessing:(In a Groovy)
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,
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.
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:
Selecting Environment at Run time:
Looping back to the next Environment:
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:
Sample Assertion Script:
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:
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.
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.
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:
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.
ReplyDeleteHi Friends,
I am using Soap UI 4.5.2 free version. Please observe project structure
My Project has only one suite
Suite has two test scenarios here (can have many)
Here in my project each test step is a test case
When I run this suite, I want each test scenario should have one excel sheet
In that excel sheet, I need to get the test case name, request xml, response xml, and status as shown below
I have tried some groovy scripting; I am sharing the script also. Please do help
//Author : Vasudev Reddy
import java.text.SimpleDateFormat
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import jxl.*
import jxl.write.*
//Get Project Name
def ProjectName= testRunner.testCase.testSuite.project.name
//log.info(ProjectName)
//Get Test Case Name
def TestCaseName= testRunner.testCase.name
//log.info(TestCaseName)
//Current Date
dateFormat = new java.text.SimpleDateFormat('dd-MMM-yyyy HH-mm-ss')
def Date = dateFormat.format(new Date())
//Selecting a folder path
def folderPath = "C:\\Vasu\\Test\\" + ProjectName +" Results"
createFolder = new File(folderPath).mkdir()
// log.info("Folderpath" + folderPath)
def workbook = Workbook.createWorkbook(new File(folderPath +"\\"+ "Results " + "(" + Date + ")" + ".xls"));
def soapuiRequests = testRunner.testCase.getTestStepsOfType(com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep)
soapuiRequests.each{
def sheet = workbook.createSheet(TestCaseName, 0)
Label header1 = new Label(0, 0, "Test case Name");
sheet.addCell(header1);
Label header2 = new Label(1, 0, "Request XML");
sheet.addCell(header2);
Label header3 = new Label(2, 0, "Response XML");
sheet.addCell(header3);
Label header4 = new Label(3, 0, "Status");
sheet.addCell(header4);
def testName = it.name;
Label testcasename = new Label(0, 1, testName);
sheet.addCell(testcasename);
Label requestxml = new Label(1, 1, context.testCase.getTestStepByName(it.name).getProperty("request").value);
sheet.addCell(requestxml);
Label responsexml = new Label(2, 1, context.testCase.getTestStepByName(it.name).getProperty("response").value);
sheet.addCell(responsexml);
Label status = new Label(3, 1, testRunner.status.toString());
sheet.addCell(status);
workbook.write()
}
workbook.close()
I am able to create the folder, excel file inside the folder, first test case row also,
But iam not able to get all test case one after another.
I know I am missing the loop somewhere please do help me
please do provide me the email address so that i can explian in clear with screenshots and send you mail. iam not able to put the images here to explain the flow
Hi Vasudev,
DeleteWere you able to solve your above script issue? Would you mind sharing your expereince and solution with me? I am facing similar issue and would solution would help me proceed.
Appreciate your help.
Thanks,
Vijay
Hi Vasudev,
ReplyDeleteSorry for the delay. guess this is your requirement.
import java.text.SimpleDateFormat
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import jxl.*
import jxl.write.*
import java.lang.String;
import java.lang.Integer;
import java.util.regex.Matcher
import java.util.regex.Pattern
//Get Project Name
def ProjectName= testRunner.testCase.testSuite.project.name
//log.info(ProjectName)
//Get Test Case Name
def TestCaseName= testRunner.testCase.name
//log.info(TestCaseName)
//Current Date
dateFormat = new java.text.SimpleDateFormat('dd-MMM-yyyy HH-mm-ss')
def Date = dateFormat.format(new Date())
//Selecting a folder path
def folderPath = "D:\\CurrencyConvertor_Results\\"
createFolder = new File(folderPath).mkdir()
// log.info("Folderpath" + folderPath)
def workbook = Workbook.createWorkbook(new File(folderPath +"\\"+ "Results " + "(" + Date + ")" + ".xls"));
def soapuiRequests = testRunner.testCase.getTestStepsOfType(com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep)
for( testCase in testRunner.testCase.testSuite.getTestCaseList() )
{
log.info("Loop 1:" + testCase.getName())
for( testStep in testCase.getTestStepList() )
{
if( testStep.getName() != "Groovy Script")
{
log.info("Loop 2:" + testStep.getName())
def sheet = workbook.createSheet( testStep.getName(), 0)
Label header1 = new Label(0, 0, "Test case Name");
sheet.addCell(header1);
Label header2 = new Label(1, 0, "Request XML");
sheet.addCell(header2);
Label header3 = new Label(2, 0, "Response XML");
sheet.addCell(header3);
Label header4 = new Label(3, 0, "Status");
sheet.addCell(header4);
Label testcasename = new Label(0, 1, testRunner.testCase.getName());
sheet.addCell(testcasename);
def request = context.expand( '${'+ testStep.getName()+'#Request}' )
Label requestxml = new Label(1, 1, request);
sheet.addCell(requestxml);
def response = context.expand( '${'+testStep.getName()+'#ResponseAsXml}' )
Label responsexml = new Label(2, 1, context.expand( '${'+response + '#Response}' ))
sheet.addCell(responsexml);
Label status = new Label(3, 1, testRunner.status.toString());
sheet.addCell(status);
}
}
workbook.write()
}
workbook.close()
Hi,
ReplyDeleteI am getting following error. do you know whether i am doing something wrong/
ue Oct 14 16:41:01 EDT 2014:ERROR:An error occurred [startup failed:
Script2.groovy: 44: unable to resolve class Label
@ line 44, column 7.
Label header1 = new Label(0, 0, "Test case Name");
^
org.codehaus.groovy.syntax.SyntaxException: unable to resolve class Label
@ line 44, column 7.
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.addError(ClassCodeVisitorSupport.java:146)
Hi Vijay,
ReplyDeleteDid you mention all the import statements as per my comment above? The code I had mentioned is a working code.
Would like to see ur complete code to check where the issue is.
Thanks,
Swami