3

I have a CSV file containing data which I read using a Bean Shell script and populate an ArrayList based upon it.Below is the code for it.

//Populate Beanshell script
import java.text.*;
import java.io.*;
import java.util.*;

ArrayList strList = new ArrayList();    

try {
File file = new File("path/to/csv");

if (!file.exists()) {
    throw new Exception ("ERROR: file not found");
}

BufferedReader bufRdr = new BufferedReader(new FileReader(file));
String line = null;

while((line = bufRdr.readLine()) != null) {
    strList.add(line);
}

bufRdr.close();   
}
catch (Exception ex) {
IsSuccess = false; 
log.error(ex.getMessage());
System.err.println(ex.getMessage());
}
catch (Throwable thex) {
System.err.println(thex.getMessage());
}

Now I want to utilize this data in a random manner so I am trying to use something like this

//Consumer bean shell script
//Not able to access strList since vars.put cannot store an object
Random rnd = new java.util.Random(); 
vars.put("TheValue",strList.get(rnd.nextInt(strList.size())));

But I am unable to do this because in vars.put I cannot store an array or a list,I can only store only primitive types.So there is no way in which I can access the populate function's ArrayList from an another BeanShell script.

How do I achieve randomization in this scenario since calling populate function each and every time is not good from a performance point of view.

4
  • And of what type is vars ? Commented Oct 15, 2014 at 11:43
  • vars is BeanShell scripting,think of it like Map.put Commented Oct 15, 2014 at 11:43
  • Can you show how you create vars ? Commented Oct 15, 2014 at 11:46
  • There is not create vars,this is specific to Jmeter,where I can store a variable like vars.put("key",value).And then I can access it like "${key}" in any Jmeter script.The issue is where I want to put a object type such as ArrayList which cannot be done,and anyone can suggest alternatives to this Commented Oct 15, 2014 at 11:48

3 Answers 3

8

vars.put only supports String values. There is vars.putObject:

Scripts can also access JMeter variables using the get() and put() methods of the "vars" variable, for example: vars.get("HOST"); vars.put("MSG","Successful"); . The get() and put() methods only support variables with String values, but there are also getObject() and putObject() methods which can be used for arbitrary objects. JMeter variables are local to a thread, but can be used by all test elements (not just Beanshell).

Sign up to request clarification or add additional context in comments.

1 Comment

have you tryed this? Actually, it throws the error: javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: org.apache.jmeter.threads.JMeterVariables.put() is applicable for argument types: (java.lang.String, java.util.ArrayList$SubList)
4

I would recommend using bsh.shared namespace, this way you will be able to store any Java object and access it even from different Thread Groups if needed.

JMeter-specific example is in the official documentation, in Sharing Variables chapter

At the end of 1st script:

bsh.shared.strList = strList;

At the beginning of the 2nd script:

List strList = bsh.shared.strList;


Random rnd = new java.util.Random(); 
vars.put("TheValue",strList.get(rnd.nextInt(strList.size())));

See How to use BeanShell: JMeter's favorite built-in component guide for more details on Beanshell scripting for JMeter.

3 Comments

This seems to be better.But now there is another issue where the values do not get replaced sometimes.It just comes like "Thevalue" instead of the actual content.Maybe is it because I am running tests multithreaded.I know this is a different question,but I got stuck with it though.Is thread safety an issue here?
You can work it around as vars.put("TheValue" + ctx.getThreadNum(), strList.get(rnd.nextInt(strList.size()))); so for 1st thread it'll be TheValue1, for the 2nd thread TheValue2, etc. There is a __threadNum() function which can be used in non-Beanshell test elements for getting current thread number: jmeter.apache.org/usermanual/functions.html#__threadNum
It is now possible to use getObject() and putObject() on vars.
2

Hope this will help someone.

For sharing variables globally, i.e. among threads in all thread groups, use props.

For e.g,

  • In setup thread group, do this
    props.put("mylist", new ArrayList());

  • Now, in post processor for every thread in the thread group, add values to the list.
    props.get("mylist").add(<some value>);

  • In tear down thread group, fetch the entire list again.
    log.info(props.get("mylist").toString());

In thread group, list is updated by multiple threads then prefer to use Vector instead of ArrayList.

Ref : scope-of-variables-sharing-among-threads-and-thread-groups

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.