Groovy & SoapUI - NumberFormatException - groovy

In SoapUI I am able to get a response from a web service that gives me a string return.
XML Node Value
soap:Envelope {Envelope}
soap:Body {Body}
EuroConvertorResponse
EuroConvertorResult 1.0966 {xsd:string}
I manage to read the response in Groovy script but I get number format exception. My code is:
String conversionString = context.expand(
'${EuroConvertorRequest#Response#declare namespace
ns1=\'http://tempuri.org/\'; //ns1:EuroConvertorResponse[1]}' )
double convertedRate = Double.parseDouble(conversionString);
The exact error I get is:
java.lang.NumberFormatException: For input string: " 1.0966 " error at line: 10.
If I hard code the response like below it works fine though!
String conversionRate = "1.0966";
double convertedRate = Double.parseDouble(conversionString);
Any idea?

You are using incorrect xpath, I believe. Supposed to query for EuroConvertorResult, not EuroConvertorResponse.
Try changing from:
String conversionString = context.expand('${EuroConvertorRequest#Response#declare namespace ns1=\'http://tempuri.org/\'; //ns1:EuroConvertorResponse[1]}' )
To:
String conversionString = context.expand('${EuroConvertorRequest#Response#declare namespace ns1=\'http://tempuri.org/\'; //ns1:EuroConvertorResult}' )
Or in fact, get the double value in single line itself by coercing as below, by adding as Double at the end:
def conversionResult = context.expand('${EuroConvertorRequest#Response#declare namespace ns1=\'http://tempuri.org/\'; //ns1:EuroConvertorResult}' ) as Double
assert conversionResult instanceof Double
Alternatively, you can use XmlSlurper to achieve the same:
def result = new XmlSlurper().parseText(context.expand('${EuroConvertorRequest#Response}').'**'.find{it.name() == 'EuroConvertorResult'}.text() as Double
log.info result
assert result instanceof Double

Related

Groovy JSONArray : org.json.JSONException: when decoding string with \"

I get no way to parse this Json which seems to be valid for me :
def diffOfApi='''[{"op":"replace","path":"/data/0/messageBody","value":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<WCS reference=\"336042800000431486\"><PREPARATION_REQUEST requestId=\"WDP_PICKVRAC3\" date=\"2022-02-08 18:33:39\"><CONTAINERS><CONTAINER containerId=\"336042800000431486_21_21121\" handle=\"CREATE\" wmsOrderId=\"WDP_PICKVRAC3\" site=\"CPEEPF\" status=\"CREATED\" referenceDate=\"2022-02-08 18:33:39\" purgeAuthorized=\"false\"><BARCODES><BARCODE main=\"false\" reusable=\"false\">336042800000431486</BARCODE></BARCODES><PACKAGING>TX</PACKAGING><WEIGHT_CHECKING mode=\"NO\"/></CONTAINER></CONTAINERS></PREPARATION_REQUEST></WCS>"}]'''
JSONArray jsonArray = new JSONArray(diffOfApi);
I get this error :
Reason:
org.json.JSONException: Expected a ',' or '}' at 71 [character 72 line 1]
at org.json.JSONTokener.syntaxError(JSONTokener.java:433)
at org.json.JSONObject.<init>(JSONObject.java:229)
at org.json.JSONTokener.nextValue(JSONTokener.java:363)
at org.json.JSONArray.<init>(JSONArray.java:115)
at org.json.JSONArray.<init>(JSONArray.java:144)
at TEST.run(TEST:32)
at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:442)
at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:433)
at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:412)
at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:404)
at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:281)
at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:142)
at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:133)
at com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
at TempTestCase1644483473725.run(TempTestCase1644483473725.groovy:25)
I think it is due to " encapsulated xml in item value
Any idea to make it working ?
You can replace the \" characters with ' to allow for JSON- and later XML-processing:
import groovy.json.*
import groovy.json.*
def diffOfApi='''[{"op":"replace","path":"/data/0/messageBody","value":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<WCS reference=\"336042800000431486\"><PREPARATION_REQUEST requestId=\"WDP_PICKVRAC3\" date=\"2022-02-08 18:33:39\"><CONTAINERS><CONTAINER containerId=\"336042800000431486_21_21121\" handle=\"CREATE\" wmsOrderId=\"WDP_PICKVRAC3\" site=\"CPEEPF\" status=\"CREATED\" referenceDate=\"2022-02-08 18:33:39\" purgeAuthorized=\"false\"><BARCODES><BARCODE main=\"false\" reusable=\"false\">336042800000431486</BARCODE></BARCODES><PACKAGING>TX</PACKAGING><WEIGHT_CHECKING mode=\"NO\"/></CONTAINER></CONTAINERS></PREPARATION_REQUEST></WCS>"}]'''
diffOfApi = diffOfApi.replaceAll( /=.{1}([^"]+)"/, "='\$1'" )
def jsonArray = new JsonSlurper().parseText diffOfApi
assert 3 == jsonArray.first().size()
def xml = new XmlSlurper().parseText jsonArray.first().value // root element points to <WCS/>
assert 'WDP_PICKVRAC3' == xml.PREPARATION_REQUEST.#requestId.text()
you have incorrectly encoded json string.
if json contains doublequote in a value " - it must be encoded as \" but inside the groovy/java code each \ also must be encoded with \\
so when you have following in code:
def x = '''{"x":"abc\"def"}'''
then actual x value at runtime would be
{"x":"abc"def"}
that is incorrect json
so, x should be defined as
def x = '''{"x":"abc\\"def"}'''
to have runtime value
{"x":"abc\"def"}

How to evaluate a String which one like a classname.methodname in SoapUI with Groovy?

I have groovy code as below:
def randomInt = RandomUtil.getRandomInt(1,200);
log.info randomInt
def chars = (("1".."9") + ("A".."Z") + ("a".."z")).join()
def randomString = RandomUtil.getRandomString(chars, randomInt) //works well with this code
log.info randomString
evaluate("log.info new Date()")
evaluate('RandomUtil.getRandomString(chars, randomInt)') //got error with this code
I want to evaluate a String which one like a {classname}.{methodname} in SoapUI with Groovy, just like above, but got error here, how to handle this and make it works well as I expect?
I have tried as blew:
evaluate('RandomUtil.getRandomString(chars, randomInt)') //got error with this code
Error As below:
Thu May 23 22:26:30 CST 2019:ERROR:An error occurred [No such property: getRandomString(chars, randomInt) for class: com.hypers.test.apitest.util.RandomUtil], see error log for details
The following code:
log = [info: { println(it) }]
class RandomUtil {
static def random = new Random()
static int getRandomInt(int from, int to) {
from + random.nextInt(to - from)
}
static String getRandomString(alphabet, len) {
def s = alphabet.size()
(1..len).collect { alphabet[random.nextInt(s)] }.join()
}
}
randomInt = RandomUtil.getRandomInt(1, 200)
log.info randomInt
chars = ('a'..'z') + ('A'..'Z') + ('0'..'9')
def randomString = RandomUtil.getRandomString(chars, 10) //works well with this code
log.info randomString
evaluate("log.info new Date()")
evaluate('RandomUtil.getRandomString(chars, randomInt)') //got error with this code
emulates your code, works, and produces the following output when run:
~> groovy solution.groovy
70
DDSQi27PYG
Thu May 23 20:51:58 CEST 2019
~>
I made up the RandomUtil class as you did not include the code for it.
I think the reason you are seeing the error you are seeing is that you define your variables char and randomInt using:
def chars = ...
and
def randomInt = ...
this puts the variables in local script scope. Please see this stackoverflow answer for an explanation with links to documentation of different ways of putting things in the script global scope and an explanation of how this works.
Essentially your groovy script code is implicitly an instance of the groovy Script class which in turn has an implicit Binding instance associated with it. When you write def x = ..., your variable is locally scoped, when you write x = ... or binding.x = ... the variable is defined in the script binding.
The evaluate method uses the same binding as the implicit script object. So the reason my example above works is that I omitted the def and just typed chars = and randomInt = which puts the variables in the script binding thus making them available for the code in the evaluate expression.
Though I have to say that even with all that, the phrasing No such property: getRandomString(chars, randomInt) seems really strange to me...I would have expected No such method or No such property: chars etc.
Sharing the code for for RandomUtil might help here.

can not pass variable to sampler's assertion in Jmeter - Groovy

I try to make a test that read from DB and assert the data
I create a JDBC request and JSR223 sampler + Jsr223 assertion.
in the sampler I created a variable called sensativity_results.
and I want to pass it to the assertion.
I used
vars.putObject("sensativity_results", sensativity_results);
and then in the assertion I try to call it and print it,
the problem is that Jmeter just not recognized the assertion,
Moreover I created another sampler called test to print the results of "sensativity_results" and Jmeter just pass it and not even execute it
int actual_sensativity ()
{
float Actual_sensativity;
int loop_num = vars.get("Loop_Number") as int;
int conversion_sense = vars.get("Conv_sens") as int;
int actual_conversion = vars.get("Conv_numbers_1") as int;
Actual_sensativity = (float) (actual_conversion/loop_num)*100;
System.out.println("************** Actual_sensativity in %: " + Actual_sensativity);
System.out.println("**conversion_sensativity: " + conversion_sense);
System.out.println("**actual_conversion: " + actual_conversion);
System.out.println("**loop number: " + loop_num);
return Actual_sensativity;
}
int sensativity_results;
sensativity_results = actual_sensativity();
vars.putObject("sensativity_results", sensativity_results);
System.out.println("sensativity_results: " + sensativity_results);
the test plan ran as expected until this step and stopped without any error it print the sensitivity results at the first sampler, and just not move on, can someone please advise?
Just put vars.put("sensativity_results", sensativity_results);
and it solved the issue
Assuming you will be using this sensativity_results variable as a String later on I would suggest storing it like:
vars.put("sensativity_results", String.valueOf(sensativity_results))
Otherwise you will get ClassCastException: java.lang.Integer cannot be cast to java.lang.String error on attempt to use it like ${sensativity_results}
Alternative way of accessing non-String variables would be using __groovy() function (available since JMeter 3.1) like:
${__groovy(String.valueOf(vars.getObject('foo')),)}

How to use Groovy script in soapUi to loop multiple time

I am new to SoapUi. I am exploring on how multiple request in soapUi is done using groovy script.
below is the example that im trying to do, based on example that i found through "googling"
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.model.testsuite.*;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
import java.util.Random
import com.eviware.soapui.model.testsuite.TestRunner.Status
// Define your testCase pointer
//def testcase = testRunner.testCase.testSuite.project.testSuites["TestSuite - User Management REST API"].getTestCaseByName ("Authenticate User")
def counterUser = testRunner.testCase.testSuite.getPropertyValue( "counter" )
int value = counterUser.toInteger()
String tester = ""
30.times {
value = value + 1
tester = "tester " + value.toString()
testRunner.testCase.testSuite.setPropertyValue( "userName", tester )
testRunner.runTestStepByName("POST - createUser - Create a User")
}
testRunner.testCase.testSuite.setPropertyValue( "counter", value.toString() )
I want to create a 30 users which start from Tester1...tester2.....tester30.
Is it possible to do this way? I keep getting an error such as NullPointerException at this line
int value = counterUser.toInteger()
I got what you say.
That is because, initially there is no value for counter which results to null and you are applying toInteger() over it.
Just change:
From:
int value = counterUser.toInteger()
To:
int value = counterUser?.toInteger() ?: 0

CS Script not working

I have setup a dynamic script (using CSScriptLibrary) in my C# program as follows:
string sqlReturnValue= cmd.ExecuteQuery();;
dynamic script = CSScript.Evaluator
.LoadCode(#"using System;
public class Script
{
string GetValue()
{
return " + sqlReturnValue + #";
}
}");
output = script.GetValue();
sqlReturnValue is a string that I get back from a SQL query similar to this:
"Salaried Grade 1".Substring(0, 7) == "Salaried") ? "CLA_SH_S" : "CLA_SH_H";
When I try to execute this the dynamic code gives me errors of "Unexpected symbol )', expecting ;'" & "Unexpected symbol :', expecting ;'"
How can I write this dynamic script such that it evaluates the ternary correctly?
IN case someone finds this useful, I was able to get this working as follows:
string sqlReturnValue = cmd.ExecuteQuery();
// Use CSScript to evaluate the test string returned from the SQL Query
var Product = CSScript.Evaluator
.CreateDelegate(#"string Product()
{
return " + sqlReturnValue + #";
}");
output = (string)Product();

Resources