Why JMeter varibles aren't set from JSR223 Groovy Assertion? - groovy

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

Related

Jmeter PostProcessor with Groovy and fetching content of response data

In JSR223 PostProcessor I am using this method to get the response data:
def json = new JsonSlurper().parseText(response)
Here is a snippet of my json output is like this
XmlItemResult:[[xPath:/Blocks/Block[001], name:abc, folder:\A\abc\a1, id:84, information:[[xPath:/Blocks/Block[001], result:Block number 1: abc], [xPath:/Blocks/Block[001]/Steps/CallSteps/Step[001], result:Call step StepNo 1],
folder:\Voice133, id:2542, information:[[xPath:/TestCases/TestCase[001],
This response, as you see contains two things which I am interested in:
folder:\A\abc\a1, id:84,
folder:\Voice133, id:2542,
I need to get the id value for only this line --> folder:\Voice133, id:2542,
note 2542 is variable and can be different each time and after each run.
I tried
json.find ("Voice133, id:(.+?),")
Your string is not a valid JSON, you can check it yourself using any online JSON validator, therefore you won't be able to use JsonSlurper, you will have to go for Regular Expressions instead.
In Groovy you can use =~ - Find Operator in order to be able to extract the required value(s), example code would be something like:
def response = 'XmlItemResult:[[xPath:/Blocks/Block[001], name:abc, folder:\\A\\abc\\a1, id:84,' +
' information:[[xPath:/Blocks/Block[001], result:Block number 1: abc],' +
' [xPath:/Blocks/Block[001]/Steps/CallSteps/Step[001], result:Call step StepNo 1], '
def matcher = (response =~ 'folder:\\\\A\\\\abc\\\\a1, id:(\\d+),')
if (matcher.find()) {
log.info('Folder ID = ' + matcher.group(1))
}
Demo:
More information: Apache Groovy - Why and How You Should Use It

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')),)}

SoapUI Load test groovy sequentially reading txt file

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>

Jenkins Build Test Case pass fail count using groovy script

I want to fetch Total TestCase PASS and FAIL count for a build using groovy script. I am using Junit test results. I am using Multiconfiguration project , so is there any way to find this information on a per configuration basis?
If you use the plugin https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin, you can access the Jenkins TestResultAction directly from the build ie.
import hudson.model.*
def build = manager.build
int total = build.getTestResultAction().getTotalCount()
int failed = build.getTestResultAction().getFailCount()
int skipped = build.getTestResultAction().getSkipCount()
// can also be accessed like build.testResultAction.failCount
manager.listener.logger.println('Total: ' + total)
manager.listener.logger.println('Failed: ' + failed)
manager.listener.logger.println('Skipped: ' + skipped)
manager.listener.logger.println('Passed: ' + (total - failed - skipped))
API for additional TestResultAction methods/properties http://javadoc.jenkins-ci.org/hudson/tasks/test/AbstractTestResultAction.html
If you want to access a matrix build from another job, you can do something like:
def job = Jenkins.instance.getItemByFullName('MyJobName/MyAxisName=MyAxisValue');
def build = job.getLastBuild()
...
For Pipeline (Workflow) Job Type, the logic is slightly different from AlexS' answer that works for most other job types:
build.getActions(hudson.tasks.junit.TestResultAction).each {action ->
action.getTotalCount()
action.getFailCount()
action.getSkipCount()
}
(See http://hudson-ci.org/javadoc/hudson/tasks/junit/TestResultAction.html)
Pipeline jobs don't have a getTestResultAction() method.
I use this logic to disambiguate:
if (build.respondsTo('getTestResultAction')) {
//normal logic, see answer by AlexS
} else {
// pipeline logic above
}
I think you might be able to do it with something like this:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
File fXmlFile = new File("junit-tests.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
println("Total : " + doc.getDocumentElement().getAttribute("tests"))
println("Failed : " +doc.getDocumentElement().getAttribute("failures"))
println("Errors : " +doc.getDocumentElement().getAttribute("errors"))
I also harvest junit xml test results and use Groovy post-build plugin https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin to check pass/fail/skip counts. Make sure the order of your post-build actions has harvest junit xml before the groovy post-build script.
This example script shows how to get test result, set build description with result counts and also version info from a VERSION.txt file AND how to change overall build result to UNSTABLE in case all tests were skipped.
def currentBuild = Thread.currentThread().executable
// must be run groovy post-build action AFTER harvest junit xml
testResult1 = currentBuild.testResultAction
currentBuild.setDescription(currentBuild.getDescription() + "\n pass:"+testResult1.result.passCount.toString()+", fail:"+testResult1.result.failCount.toString()+", skip:"+testResult1.result.skipCount.toString())
// if no pass, no fail all skip then set result to unstable
if (testResult1.result.passCount == 0 && testResult1.result.failCount == 0 && testResult1.result.skipCount > 0) {
currentBuild.result = hudson.model.Result.UNSTABLE
}
currentBuild.setDescription(currentBuild.getDescription() + "\n" + currentBuild.result.toString())
def ws = manager.build.workspace.getRemote()
myFile = new File(ws + "/VERSION.txt")
desc = myFile.readLines()
currentBuild.setDescription(currentBuild.getDescription() + "\n" + desc)

SoapUI + Groovy + Get 3 test data from 3 different environment respectively

In SoapUI, We have 3 different environment and 3 different test data property files.
So my problems are:
How to set 3 different end points in SoapUI?
How to get test data as per the environment using Groovy?
I try to answer your questions
1.- How to set 3 different end points in SoapUI.
Set your test steps URL with a property like:
http://${#Project#endpoint}
And add the endpoint property in your test data file.
2.- How to get test data as per the environment using Groovy.
If you have a typical property file with key=value you can use the code shown below:
// read property file
def properties = new java.util.Properties();
properties.load( new java.io.FileInputStream( "/tmp/sample.properties" ));
proj = testRunner.testCase.testSuite.project;
def names = [];
names = properties.propertyNames();
while( names.hasMoreElements() )
{
def name = names.nextElement();
log.info name + " " + properties.getProperty(name);
proj.setPropertyValue(name, properties.getProperty(name)) ;
}
With this you save all properties in the project level, if you prefer to save in testCase or testSuite use testRunner.testCase or testRunner.testCase.testSuite instead of testRunner.testCase.testSuite.project.
Hope this helps,

Resources