How to set Project property value using Groovy? - groovy

I want to set property in Project level, with my groovy code I can set a property in TestCase level. How can do the same to set property in Project level
Here is my code:
import groovy.json.JsonSlurper
responseContent = testRunner.testCase.getTestStepByName("TestStepName").getPropertyValue("response")
slurperresponse = new JsonSlurper().parseText(responseContent)
slurperresponse.id.toString()
log.info (slurperresponse.id.toString())
property_name = 'a'
def idProperty = setupTestCase.getProperty(property_name).toString()
setupTestCase.setPropertyValue('a',slurperresponse.a.toString())
Here I'm setting the TestCase property "a" from the response of a TestStepName.
I'm using Soapui.
Thank you

You can add a project property in SOAPUI using groovy with the follow code:
testRunner.testCase.testSuite.project.setPropertyValue("yourProp", yourValue )
Using your code:
import groovy.json.JsonSlurper
responseContent = testRunner.testCase.getTestStepByName("TestStepName").getPropertyValue("response")
slurperresponse = new JsonSlurper().parseText(responseContent)
slurperresponse.id.toString()
log.info (slurperresponse.id.toString())
testRunner.testCase.testSuite.project.setPropertyValue("a",slurperresponse.a.toString())
Hope this helps,

Related

SoapUI Groovy script: Create new project using command line

I am trying to create Soapui project using groovy script.
When running it directly from SoapUI, the Script is working correctly and new Project with WSDL is created.
The script is created in: Project -> TestSuite -> TestCase -> Groovy script
import com.eviware.soapui.impl.wsdl.*
import com.eviware.soapui.impl.WsdlInterfaceFactory
String Release = "xxx.yyy";
String projectName = "Test_$Release" + ".xml";
String projectPath = "D:/work/";
String fullProjectPath = "$projectPath$projectName";
String pathToWSDL = "D:/work/AWSECommerceService.wsdl.xml";
log.info ("Release value is $Release");
log.info ("Projet path is $projectPath");
log.info ("Project name is $projectName");
log.info ("pathToWSDL $pathToWSDL");
log.info ("fullProjectPath $fullProjectPath");
def currentProject = testRunner.testCase.testSuite.project;
WsdlProject project = currentProject
.getWorkspace()
.createProject(projectName, new File(fullProjectPath));
WsdlInterface iface = WsdlInterfaceFactory.importWsdl(project,pathToWSDL, true )[0]
context.testCase.testSuite.project.save("");
The script is working correctly when from SoapUI. But, failing when run it using testrunner.bat as given below:
testrunner.bat "D:\Ivo\Project.xml"
It is returning following error:
Error:java.lang.NullPointerException: Cannot invoke method createProject() on null object
Can you try change as given below:
From:
WsdlProject project = currentProject
.getWorkspace()
.createProject(projectName, new File(fullProjectPath));
To:
WsdlProject project = new WsdlProject();
project.setName(projectName);
//your statements goes here
//finally save project
project.saveAs(fullProjectPath);

Groovy Binding: Cannot cast object with class 'custompackage.CustomClass' to class 'custompackage.CustomClass'

Using Groovy Binding to execute scripts from a main controller and attempting to pass a custom object, I get the error mentioned in the title.
Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'custompackage.CustomClass#60099951' with class 'custompackage.CustomClass' to class 'custompackage.CustomClass'
Here's the relevant code:
// Controller.groovy
import custompackage.CustomClass
CustomClass test = new CustomClass()
def binding = new Binding()
def engine = new GroovyScriptEngine('./src')
binding.setProperty("test", test)
engine.run("CustomScript.groovy", binding)
The file being run with above:
// CustomScript.groovy
import custompackage.CustomClass
CustomClass t
if(!binding.variables.containsKey("test")){
t = new CustomClass()
} else {
t = test
}
I'm defining the CustomClass t at the beginning for the purpose of autocomplete in my IDE. When running as def t it works fine.
I know the object is being passed correctly, due to the exception (and further printing of the object)
The error occurs on t = test
Why is Groovy trying to cast an object of the same type to it's type, and then failing to do so? And is there a fix that will still allow me to keep the statically typed t?
Thanks!
It seems custompackage.CustomClass in Controller.groovy is not the same as in CustomScript.groovy.
I checked the class instances in CustomScript.groovy with the debugger and found something interesting:
def a = CustomClass.class // Debugger: a={Class#1499} "class custompackage.CustomClass"
def b = test.class // Debugger: b={Class#1187} "class custompackage.CustomClass"
While when using GroovyShell instead of GroovyScriptEngine in Controller.groovy I get:
def a = CustomClass.class // Debugger: a={Class#1185} "class custompackage.CustomClass"
def b = test.class // Debugger: b={Class#1185} "class custompackage.CustomClass"
and the assignment t = test works without error.
The Controller.groovy file using GroovyShell looks like this:
// Controller.groovy
import custompackage.CustomClass
CustomClass test = new CustomClass()
def binding = new Binding()
def shell = new GroovyShell(binding)
binding.setProperty("test", test)
shell.evaluate(new File("CustomScript.groovy"))
I checked the documentation of GroovyScriptEngine and found a constructor which takes a ClassLoader as argument. Maybe that's the way to go but I don't know for sure.

null object error when calling code from script assertion - soapui (creating test Runner in script assertion)

In a soapui groovy script test step I've this.
context.setProperty("searchA", new searchA());
class searchA{
def testRunner
def searchA(testRunner){
this.testRunner=testRunner
}
def search(a,b){
def search_TestCase = testRunner.testCase.testSuite.getTestCaseByName("Search")
search_TestCase.setPropertyValue("ABC", a)
search_TestCase.setPropertyValue("DEF", b)
search_TestCase.run(new com.eviware.soapui.support.types.StringToObjectMap(), false)
}
}
and in an assertion script in a different test suite I am calling the above code like this.
scripts = messageExchange.modelItem.testStep.testCase.testSuite.project.testSuites["Test"]
scripts.testCases["Lib123"].testSteps["TestLib123"].run(context.getTestRunner(),context)
context.searchA.search("value1","value2")
but this gives me error "can not get property testCase on null object". whats wrong here?
I am not seeing null object error now. The issue was that testRunner is not available in script assertion so we need to create it like this in script assertion and then pass it in the caller method.
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
import com.eviware.soapui.support.types.StringToObjectMap
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext
testCase = messageExchange.modelItem.testStep.testCase
tcRunner = new WsdlTestCaseRunner( testCase, new StringToObjectMap() );
context.searchA.search("value1","value2",tcRunner)
This thread helped me.

How to create an object in Custom properties using groovy?

i'm new in soapui and groovy.
i'm trying to create an object in Custom Properties, the value of the object is already retrived with a groovy code from json response after a first request.
How can i create the object in Custom Properties?
Here is the first Groovy code which extract the value of "id" from the json response:
import groovy.json.JsonSlurper
responseContent = testRunner.testCase.getTestStepByName("Request_1").getPropertyValue("response")
slurperresponse = new JsonSlurper().parseText(responseContent)
log.info (slurperresponse.id)
Output:
INFO:100
I tried this:
def Id = context.expand('${Id#Id}')
context.getTestCase().setPropertyValue('Id', Id);
The value of the variable "Id" in Custom Properties of the TestCase is empty
What i was expecting is to get Id=100
THank you

Executing a Java jar file from within a SoapUI groovy script not working

I am new to SoapUI and Groovy so please forgive this post as it has been posted a number of times in Stackoverflow however I cannot find a fix.
SoapUI version: 4.5.2
I have 2 questions if you guys don't mind:
I have an executable jar file that I've put in the the \bin\ext directory along with another jar that is considered a dependency jar within the code in the jar so I hope it will reference there. The groovy code I found in Stackoverflow that should execute this jar is as follows but does not work as I don't see any output anywhere in the SoapUI directory.
Here is the code:
def command = "java -jar UpdateAppIdXMLRequest.jar file.xml"
def process = command.execute()
process.waitFor()
def output = process.in.text
log.info output
This jar creates 25 xml files that should be able to be picked up by the SoapUI and put them in as TestSteps in the same project. In my java code in what path do I put these files?
Here is the code in my jar:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
class UpdateAppIdXMLRequest {
static main(args) {
try {
SAXBuilder builder = new SAXBuilder();
File xmlFile = new File("c:\\file.xml");
Document doc = (Document) builder.build(xmlFile);
Element rootNode = doc.getRootElement();
// Create loop to create 25 testStepApps
for (int i = 1; i < 26; i++) {
// Get current AppID, incrementAppID and update the ApplicationNumber attribute value for next test script.
int appID = Integer.parseInt(rootNode.getAttributeValue("ApplicationNumber"));
appID++;
String appIDValue = Integer.toString(appID);
rootNode.getAttribute("ApplicationNumber").setValue(appIDValue);
XMLOutputter xmlOutput = new XMLOutputter();
// Create new XML file with next AppID
xmlOutput.setFormat(Format.getPrettyFormat());
xmlOutput.output(doc, new FileWriter("c:\\testStepApp" + i + ".xml"));
// xmlOutput.output(doc, System.out);
// System.out.println("File updated!");
}
} catch (IOException io) {
io.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
}
}
}
Any help/direction would be appreciated.
Thanks.
In order to do so, I recommend that you use directly groovy test step instead of a jar, this way you have more flexibility an you have not recompile the jar each time you must need to change something.
So, in order to achieve your goal, at first you need to create a TestCase inside your project, create a SOAP Test Step and Groovy Test Step inside like this:
I will use SOAP Test Step to create the other test steps (to create test steps it needs the wsdl:operation and so on, and it's more easy to copy the test step that create directly).
In the Groovy Test Step I will put the necessary code to do the work which is showed below:
import com.eviware.soapui.support.XmlHolder
import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestRequestStepFactory
// read your request template
def requestFile = new File("C:/file.xml");
// parse it as xml
def requestXml = new XmlHolder(requestFile.text)
// get the current testCase to add testSteps later
def tc = testRunner.testCase;
// get the testStep as template to create the other requests
def tsTemplate = tc.getTestStepByName("Template");
// loop to create 25 testStep
for(int i = 1; i < 26; i++){
// xpath expression to get applicationNumber attribute in root node
def xpathNodeAttr = "/*/#ApplicationNumber";
// get the root node attribute applicationNumber throught an XPATH
int appId = Integer.parseInt(requestXml.getNodeValue(xpathNodeAttr));
// add 1 to appId
appId++;
// set the value again in the attribute
requestXml.setNodeValue(xpathNodeAttr,appId);
def testStepName = "TestStep_ApplicationNumber_"+ String.valueOf(appId)
log.info testStepName;
log.info testStepName.getClass().getName()
log.info tc.getClass().getName()
// create a new testStepConfig
def testStepFactory = new WsdlTestRequestStepFactory();
def testStepConfig = testStepFactory.createConfig( tsTemplate.getOperation(), testStepName )
// add the new testStep to TestCase
def newTestStep = tc.insertTestStep( testStepConfig, -1 )
// set the request which just create
newTestStep.getTestRequest().setRequestContent(requestXml.getXml())
}
This code it's basically your java code "translated" to groovy and added the necessary code to create the test steps. In a few words this code reads a request from a file, and create 25 test steps in the current test case using the request, in each request it only changes the ApplicationNumber attribute of the root node adding it +1.
EDIT BASED ON COMMENT:
If you use a REST Request step instead of SOAP Request Step you have to change a bit your groovy code to use com.eviware.soapui.impl.wsdl.teststeps.registry.RestRequestStepFactory and getTestRequest() method on it. So if you have a REST Service with a POST method create a Test Case with a REST Request test step and Groovy Test Step like this:
And use this groovy code instead, basically this code it's the same and works like the code above and makes the same thing with REST Request instead of SOAP Request:
import com.eviware.soapui.support.XmlHolder
import com.eviware.soapui.impl.wsdl.teststeps.registry.RestRequestStepFactory
// read your request template
def requestFile = new File("C:/file.xml");
// parse it as xml
def requestXml = new XmlHolder(requestFile.text)
// get the current testCase to add testSteps later
def tc = testRunner.testCase;
// get the testStep as template to create the other requests
def tsTemplate = tc.getTestStepByName("Template");
// loop to create 25 testStep
for(int i = 1; i < 26; i++){
// xpath expression to get applicationNumber attribute in root node
def xpathNodeAttr = "/*/#ApplicationNumber";
// get the root node attribute applicationNumber throught an XPATH
int appId = Integer.parseInt(requestXml.getNodeValue(xpathNodeAttr));
// add 1 to appId
appId++;
// set the value again in the attribute
requestXml.setNodeValue(xpathNodeAttr,appId);
def testStepName = "TestStep_ApplicationNumber_"+ String.valueOf(appId)
log.info testStepName;
log.info testStepName.getClass().getName()
log.info tc.getClass().getName()
// create a new testStepConfig
def testStepFactory = new RestRequestStepFactory();
def testStepConfig = testStepFactory.createConfig( tsTemplate.getTestRequest(), testStepName )
// add the new testStep to TestCase
def newTestStep = tc.insertTestStep( testStepConfig, -1 )
// set the request which just create
newTestStep.getTestRequest().setRequestContent(requestXml.getXml())
}
Hope this helps.

Resources