Ask a Question

How to write a reusable script Library

MartinSpamer
Frequent Contributor

How to write a reusable script Library

I've found the need to define a common Library of reusable Groovy Scripts for use with SOAPUI community edition, there isn't a tutorial or established examples on how this can be achieved so here is an example of how I did this.

1) Define a new TestSuite in the root of your project called Library.
2) Disable the Library TestSuite so that it doesn't get run in an uncontrolled manner.
3) Define a TestCase under Library, I name this after the module-name.
4) Define a Groovy Script, I give this the name of the Groovy Class that is going to contain my reusable code.

 

class Example {
def log
def context
def testRunner
// Class constructor with same case as Class name
def Example(logIn,contextIn,testRunnerIn) {
this.log = logIn
this.context = contextIn
this.testRunner = testRunnerIn
}
}


5) Add the reusable code as method, pass parameters as necessary.

def execute(message) {
// do some stuff to prove I've run with right context, etc.
log.info testRunner
log.info context
log.info "return "+message
return message
}


6) We need to instance of the class; add the following to the end of the Script, outside the class definition. This will place the instance in the project's context.

context.setProperty( "example", new Example( log, context, testRunner) )
log.info "Library Context:"+context


7) You can now reuse the instance in any Groovy Script, with the following Groovy code.

// get a reference to the library TestSuite
library = testRunner.testCase.testSuite.project.testSuites["Library"]

// find the module within the library
module = library.testCases["module-name"].testSteps["Example"]

// initialise the library; which places an instance of Example in the context
module.run(testRunner, context)

// get the instance of example from the context.
def example = context.example

// run the method, with parameter
log.info "example.execute() = " + example.execute("Tester")


😎 Add more modules, classes or methods as necessary.
9) The instance can be added to the Global context if you want to use it across SOAPUI projects.

30 REPLIES 30
SmartBear_Suppo
SmartBear Alumni (Retired)

1. Why don't you just add the library as "Run TestCase" test step: http://www.soapui.org/Functional-Testin ... tests.html

2. Also as part of SoapUI Pro, we do have the ability to define a global Groovy script library:
http://www.soapui.org/Scripting-Propert ... pt-library

Did my reply answer your question? Give Kudos or Accept it as a Solution to help others. ⬇️⬇️⬇️
Jack21Z
Occasional Contributor

Hi

What if I have two or more classes under "module-name", how can I instantiate all the classes on my groovy script

ex.
Lib
--module-name
--example
--other_class
--other_class2
--other_class3
--....


Other_Test_Suite
--TestCase
--groovy_script

Do I have to do the following?:

library = testRunner.testCase.testSuite.project.testSuites["Library"]
module = library.testCases["module-name"].testSteps["Example"]
module2 = library.testCases["module-name"].testSteps["other_class"]
module3 = library.testCases["module-name"].testSteps["other_class2"]
....
module.run(testRunner, context)
module2.run(testRunner, context)
module3.run(testRunner, context)



Or there are other ways like:

library = testRunner.testCase.testSuite.project.testSuites["Library"]
for(int i = 0; i <= [i]number_of_classes[/i]; i++){
library.testCases["module-name"].testSteps[i].run(testRunner, context)
}

// [i]i[/i] is the order of class under module_name



Thanks in advance,
Jack
MartinSpamer
Frequent Contributor

Jack21Z wrote:


What if I have two or more classes under "module-name", how can I instantiate all the classes on my groovy script


library = testRunner.testCase.testSuite.project.testSuites["Library"]
module = library.testCases["module-name"].testSteps["Example"]
module2 = library.testCases["module-name"].testSteps["other_class"]
module3 = library.testCases["module-name"].testSteps["other_class2"]
....
module.run(testRunner, context)
module2.run(testRunner, context)
module3.run(testRunner, context)



Or there are other ways like:

library = testRunner.testCase.testSuite.project.testSuites["Library"]
for(int i = 0; i <= [i]number_of_classes[/i]; i++){
library.testCases["module-name"].testSteps[i].run(testRunner, context)
}




I haven't tested them, but both of those approaches should work.

I just prefer to keep them seperate as per the single responsibility principle.
SmartBear_Suppo
SmartBear Alumni (Retired)

Interesting. Thanks for sharing, Martin!

Manne Fagerlind
SmartBear Sweden

Did my reply answer your question? Give Kudos or Accept it as a Solution to help others. ⬇️⬇️⬇️
VaishaliSharma
Not applicable

Thanks A lot...Your script was really helpful
mamar
Contributor

Hi,
I use this reusuable script logic and was able to run in SoapUI 4.5.2 free version. But the same project (with the same scripts) is not running in SoapUI Pro 4.6.4 licensed version. Below is my script structure.

Project A
---Test Suite 1
------Test Case 1
----------(in the setupscript i have a code to call and run my common class method in another project as below)

library = testRunner.getTestCase().getTestSuite().getProject().getWorkspace().getProjectByName("Library")
suitename = library.getTestSuiteByName("Driver_Scripts");
module1 = suitename.testCases["Methods"].testSteps["Initialize_DataSetup"]
module1.run(testRunner, context)
def startTestData = context.InitializeTestData
startTestData.FirstData(<with some parameters>)

My Library project looks like below.

Library
---Driver_Scripts
------Methods
---------(here i have the 'Initialize_DataSetup' test case)

when i run the same script in SoapUI Pro 4.6.4, i get the below error. Could any one please help me to resolve.

Thu Jan 30 10:46:39 EST 2014:ERROR:java.lang.NullPointerException
java.lang.NullPointerException
at com.eviware.soapui.support.log.InspectorLog4JMonitor.getLogArea(InspectorLog4JMonitor.java:91)
at com.eviware.soapui.support.log.Log4JMonitor$getLogArea.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at InitializeTestData.FirstData(Script1.groovy:27)
at InitializeTestData$FirstData.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at Script9.run(Script9.groovy:50)
at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.run(SoapUIGroovyScriptEngine.java:96)
at com.eviware.soapui.support.scripting.groovy.SoapUIProGroovyScriptEngineFactory$SoapUIProGroovyScriptEngine.run(SourceFile:89)
at com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase.runSetupScript(WsdlTestCase.java:934)
at com.eviware.soapui.impl.wsdl.panels.testcase.WsdlTestCaseDesktopPanel$SetupScriptGroovyEditorModel$1.actionPerformed(WsdlTestCaseDesktopPanel.java:640)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
shabar
Contributor

Hi Martin,

Is it possible to have several methods under one class.

Added following method into you original code. That is it.


def executeBlank()
{
// do some stuff to prove I've run with right context, etc.
log.info testRunner
log.info context
log.info "return Hello"+


//return "message"
}



Then I got following error when there are two methods under one class


ERROR:org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script27.groovy: 33: unexpected token: } @ line 33, column 4.



Cheers
mamar
Contributor

Hi Martin,

I found out and resolved the issue which i posted in my previous post. The problem is i had a code "com.eviware.soapui.SoapUI.logMonitor.getLogArea("soapUI log").clear()" in which the text "soapUI log" is "SoapUI log" in Pro version. Now all my code is running perfectly.

But i face another issue. When i run from soapui tool, all my suites are running without any issues. But when i run from command prompt, i get an error like below. Could you please help me to resolve..? i use the same reusable code concept as you have. My reusable code is in different project(Library) and my calling code is in different project. When i run this project i get the below error.

...
...
...
command: cmd.exe /C testrunner.bat -s<suite> -c<testcase> -r -f"C:\TestRunner Reports" -R"TestSuite Report" -EDefault "C:\project.xml"
09:47:34,756 INFO [SoapUI] Adding [C:\Program Files (x86)\SmartBear\SoapUI-4.6.4\bin\ext\postgresql-8.3-604.jdbc3.jar] to extensions classpath
09:47:34,757 INFO [SoapUI] Adding [C:\Program Files (x86)\SmartBear\SoapUI-4.6.4\bin\ext\postgresql-8.3-604.jdbc4.jar] to extensions classpath
09:47:34,759 INFO [SoapUI] Adding [C:\Program Files (x86)\SmartBear\SoapUI-4.6.4\bin\ext\sqljdbc.jar] to extensions classpath
09:47:35,147 INFO [DefaultSoapUICore] initialized soapui-settings from [C:\Users\PAR964\soapui-settings.xml]
09:47:35,458 INFO [DefaultSoapUICore] Adding plugin from [C:\Program Files (x86)\SmartBear\SoapUI-4.6.4\bin\plugins\soapui-groovy-console-plugin-1.0-plugin.jar]
09:47:36,481 INFO [WsdlProject] Loaded project from [file:/C:project.xml]
09:47:38,157 ERROR [AbstractTestRunner] Exception during Test Execution
java.lang.NullPointerException: Cannot invoke method getProjectByName() on null object
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:77)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:45)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
....
....
....
gireeshpunjot
Not applicable

Hi All,

I am new to SOAP UI.

I tried writing the class but getting error: Unexpected token: context @ line 23.
I have attached the screenshot of the script and the error message.

Please help.
mamar
Contributor

Place the "Context.setProperty(.....)" line (line 23 in your code) outside of the class and you should able to run.
cancel
Showing results forΒ 
Search instead forΒ 
Did you mean:Β