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')),)}
Related
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.
I'm trying to set Jmeter variables extracted from Jmeter properties inside JSR223 Groovy Assertion.
Jmeter properties in which I'm interested looks like:
...
created_blob_A_6= fde65de0-3e32-11e8-a5b4-3906549016d8
created_blob_A_8= fef92d70-3e32-11e8-a5b4-3906549016d8
created_blob_A_9= ff775e20-3e32-11e8-bac3-e51250ffea15
created_blob_B_1= fd7302a0-3e32-11e8-a5b4-3906549016d8
created_blob_B_10= 00141350-3e33-11e8-bac3-e51250ffea15
...
In order to extract values from Jmeter properties, I've created JSR223 Groovy the following Assertion script:
def readParamPrefix = 'created_blob'
def writeParamPrefix = 'blob_to_delete'
def chucnkTypes = 'A'..'E'
def newBlobCounter = 1
chucnkTypes.each{ chunkLetter ->
(1..10).each{ streamNumber ->
String readParamName = readParamPrefix + '_' + chunkLetter + '_' + streamNumber
log.info('Read param name: ' + readParamName)
String writeParamName = writeParamPrefix + '_' + newBlobCounter
log.info('Write param name: ' + writeParamName)
String blob_id_to_delete = props.get(readParamName).toString().trim()
log.info('' + readParamName + ' => ' + writeParamName + ' (' + blob_id_to_delete + ')')
vars.put(writeParamName.toString(), blob_id_to_delete.toString())
newBlobCounter++
}
}
The script doesn't work for JMeter variables, but works fine for JMeter properties. Here is how JMeter properies look like:
JMeterProperties:
...
blob_to_delete_1=9b1c4f40-3e36-11e8-a5b4-3906549016d8
blob_to_delete_10=9da5e050-3e36-11e8-bac3-e51250ffea15
blob_to_delete_11=9b235420-3e36-11e8-bac3-e51250ffea15
blob_to_delete_50=9b656630-3e36-11e8-bac3-e51250ffea15
Could you tell me, how I can fix my code for setting up JMeter variables correctly?
I don't see any problem with your code:
So I would recommend:
Checking jmeter.log file for any suspicious entries
Checking what variables are defined using Debug Sampler and View Results Tree listener combination. See How to Debug your Apache JMeter Script article for more information on getting to the bottom of JMeter script failure or unexpected behavior.
Don't use ${varName} in scripts, Notice JSR223 Best Practices:
ensure the script does not use any variable using ${varName} as caching would take only first value of ${varName}. Instead use :
vars.get("varName")
You can also pass them as Parameters to the script and use them this way.
After you change it, look for errors in logs if it still doesn't works
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
I am using free version of soapui. In my load test, I want to read request field value from a text file. The file looks like following
0401108937
0401109140
0401109505
0401110330
0401111204
0401111468
0401111589
0401111729
0401111768
In load test, for each request I want to read this file sequentially. I am using the code mentioned in Unique property per SoapUI request using groovy to read the file. How can I use the values from the file in a sequential manner?
I have following test setup script to read the file
def projectDir = context.expand('${projectDir}') + File.separator
def dataFile = "usernames.txt"
try
{
File file = new File(projectDir + dataFile)
context.data = file.readLines()
context.dataCount = context.data.size
log.info " data count" + context.dataCount
context.index = 0; //index to read data array in sequence
}
catch (Exception e)
{
testRunner.fail("Failed to load " + dataFile + " from project directory.")
return
}
In my test, I have following script as test step. I want to read the current index record from array and then increment the index value
def randUserAccount = context.data.get(context.index);
context.setProperty("randUserAccount", randUserAccount)
context.index = ((int)context.index) + 1;
But with this script, I always get 2nd record of the array. The index value is not incrementing.
You defined the variable context.index to 0 and just do +1
You maybe need a loop to read all values.
something like this :
for(int i=0; i <context.data.size; i++){
context.setProperty("randUserAccount", i);
//your code
}
You can add this setup script to the setup script section for load test and access the values in the groovy script test step using:
context.LoadTestContext.index =((int)context.LoadTestContext.index)+1
This might be a late reply but I was facing the same problem for my load testing for some time. Using index as global property solved the issue for me.
Index is set as -1 initially. The below code would increment the index by 1, set the incremented value as global property and then pick the context data for that index.
<confirmationNumber>${=com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( "index", (com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( "index" ).toLong()+1 ).toString()); return (context.data.get( (com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( "index" )).toInteger())) }</confirmationNumber>
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();