I have several user defined variables set via properties i would like to validate.
I can use a jsr223 sampler to validate these but i dont want to duplicate all the names which are already set in the user defined variables.
Is there some programatic way to get hold of the declared user defined variables, possibly via the sampler or context variables?
There is vars shorthand for JMeterVariables class instance which holds all the JMeter Variables (including the ones you set via User Defined Variables class).
Check out Top 8 JMeter Java Classes You Should Be Using with Groovy article for more information on vars and other JMeter API shorthands available for the JSR223 Test Elements.
However this way you will get all the JMeter Variables including pre-defined ones
If you want to validate only the variables you have defined in the User Defined Variables configuration element you can play a little trick with the Reflection:
import org.apache.jmeter.config.Arguments
import org.apache.jorphan.collections.SearchByClass
def engine = engine = ctx.getEngine()
def test = engine.getClass().getDeclaredField('test')
test.setAccessible(true)
def testPlanTree = test.get(engine)
SearchByClass<Arguments> udvSearch = new SearchByClass<>(Arguments.class)
testPlanTree.traverse(udvSearch)
Collection<Arguments> udv = udvSearch.getSearchResults()
udv.each { arguments ->
0.upto(arguments.size() - 1, { rowNum ->
def arg = arguments.getArgument(rowNum)
log.info('Variable name = ' + arg.getName() + ', variable value = ' + arg.getValue())
})
}
Related
Based on this thread - Jmeter - how to return multiple ID(s) based on the array (match JSON path with array)
I managed to get ID's, for every single member of the array.
Now I need to alternate the code and to have a variable for every single ID.
What i tried is:
vars.get('array').replace("[", "").replace("]", "").split(", ").each { country ->
def result = new groovy.json.JsonSlurper().parse(prev.getResponseData()).payload.find { entry -> entry.name == country.trim() }
vars.put("tim" + ${__counter(,)}, result.id as String);
}
But, I am only able to get a single variable.
What should I do in order to save every single result.id, into variables like:
tim1, tim2, tim3...
Don't inline JMeter Functions or Variables into Groovy scripts.
As per JMeter Documentation:
The JSR223 test elements have a feature (compilation) that can significantly increase performance. To benefit from this feature:
Use Script files instead of inlining them. This will make JMeter compile them if this feature is available on ScriptEngine and cache them.
Or Use Script Text and check Cache compiled script if available property.
When using this feature, ensure your script code does not use JMeter variables or JMeter function calls directly in script code as caching would only cache first replacement. Instead use script parameters.
So I would rather recommend amending your code as follows:
vars.get('array').replace("[", "").replace("]", "").split(", ").eachWithIndex { country, index ->
def result = new groovy.json.JsonSlurper().parse(prev.getResponseData()).payload.find { entry -> entry.name == country.trim() }
if (result != null) {
vars.put("tim" + (index + 1), result.id as String);
}
}
Demo:
More information: Apache Groovy - Why and How You Should Use It
I am trying to create some dynamic user defined variables, use them within http requests in JMETER and also save them to file. Basically I'm testing the creation of accounts and would like to save the accounts I've created.
The problem is when I use User Defined Variables and then set the values as below, it only generated the random strings once and in subsequent loops it uses the same data and fails as email already exists:
FIRSTNAME1 Bob${__RandomString(10,abcdefghijklmnopqrstuvwxyz,)}
LASTNAME1 Surname${__RandomString(10,abcdefghijklmnopqrstuvwxyz,)}
EMAIL1 Bob${__RandomString(10,abcdefghijklmnopqrstuvwxyz,)}#emailaddres.com
To save this to file I use:
name1 = vars.get("EMAIL1");
name2 = vars.get("FIRSTNAME1");
name3 = vars.get("LASTNAME1");
f = new FileOutputStream("C://test/Register_new_user_Jmeter.csv", true);
p = new PrintStream(f);
this.interpreter.setOut(p);
p.println(name1 + "," + name2 + "," + name3);
f.close(
How do I set this up so I can generate random strings, use them to create new accounts and also save the info to file? Thanks
Yes, User Defined Variables are used for defining once (static) variables, use other component, especially User Parameters for dynamic values.
If a runtime element such as a User Parameters Pre-Processor or Regular Expression Extractor defines a variable with the same name as one of the UDV variables, then this will replace the initial value, and all other test elements in the thread will see the updated value.
User Parameters are creating variables same as User Defined Variable, but can override pervious values
If there are more threads than values, the values get re-used. For example, this can be used to assign a distinct user id to be used by each thread. User variables can be referenced in any field of any JMeter Component.
I have a small script that has it's own properties and a single Thread Group. Sometimes I need to merge this test script into a bigger test plan that has more than a single Thread Group. I need a way to say if there's only 1 thread group then apply these user defined variables. Any ideas? I'm thinking I would add an If Controller but I can't seem to find what condition I would put.
You can instead add If condition about your TestPlan,
For example if your small script is 1.jmx check
${jexl3( "1.jmx" == "${__TestPlanName}")}
Also you can add a variable in Test plan as amILong with true value and check if it exists.
Actually you can get the number of Thread Groups in the Test Plan, but it will require some scripting assuming using JMeter API.
Add JSR223 Sampler somewhere to your Test Plan
Make sure groovy language is selected in "Language" dropdown
Put the following code into "Script" area:
import org.apache.jmeter.engine.StandardJMeterEngine
import org.apache.jmeter.threads.ThreadGroup
import org.apache.jorphan.collections.HashTree
import org.apache.jorphan.collections.SearchByClass
import java.lang.reflect.Field
def engine = ctx.getEngine()
def test = engine.getClass().getDeclaredField("test")
test.setAccessible(true)
def testPlanTree = (HashTree) test.get(engine)
def threadGroupSearch = new SearchByClass<>(ThreadGroup.class)
testPlanTree.traverse(threadGroupSearch)
def threadGroups = threadGroupSearch.getSearchResults().size()
log.info('Detected ' + threadGroups + ' Thread Groups in the Test Plan')
if (threadGroups == 1) {
props.put('foo', 'bar')
}
else {
props.put('foo', 'baz')
}
If there is only one Thread Group in the Test Plan the above code will create foo JMeter Property with the value of bar, in the other case(s) the property value will be baz. You will be able to refer the property via __P() function as ${__P(foo,)} where required, i.e. in the If Controller.
Demo:
More information: Apache Groovy - Why and How You Should Use It
I need to create a set of local variables at the beginning of a Keyword test and then use them later while executing the Test.
Is there any possibility to create local variables dynamically as like project variables which can be created dynamically.
Project.variables.<variable_name> = "project_variable_value"
in the similar fashion can we create any variable associated to any keyword test
Keywordtests.<generic_keyword_test_name>.variables.<variable_name> = "local_variable_value"
Sure, you can do this. Please see this example:
function Test11()
{
if (KeywordTests.Test1.Variables.VariableExists("MyVariable") == false) {
KeywordTests.Test1.Variables.AddVariable("MyVariable", "String");
}
KeywordTests.Test1.Variables.MyVariable = "test value";
Log.Message(KeywordTests.Test1.Variables.MyVariable);
}
Information on the AddVariable method can be found in the AddVariable Method help topic.
I have problems picking up variables set by the Regular Expression
Extractor in a Beanshell.
I have an HTTP Request sampler which returns a list of 50 numbers in random form (4, 2, 1, 3....50, 45) which I have extracted via regEx.
Now I want to get each and every numbers in a variable so I used again regEx with expression (.+?)(,) on JMeter variable from step# 1 above.
I have problem here at this step when I am using BeanShell to access these values
Wasn't very sure I used below:
long var1 = Integer.parseInt(vars.get("Number_i"));
print("Value of var1: " +var1);
Practically I want to do this:
for (i=0; i<50; i++) {
if (var1==1) {
do this
}
}
I am not adept at Jmeter, so please bear with me.
Given you extract variables using Regular Expression Extractor and you have > 1 match you already have multiple variables, you can check them using Debug Sampler and View Results Tree listener combination
So you can access variables in JMeter like:
${number_1}
${number_2}
and in Beanshell test elements using vars shorthand which stands for JMeterVariables class instance like:
vars.get("number_1");
vars.get("number_2");
Example code which will iterate all the matches and "do something" when current variable value is "1"
int matches = Integer.parseInt(vars.get("number_matchNr"));
for (int i=1; i<=matches; i++) {
if (vars.get("number_" + i).equals("1")) {
log.info("Variable: number_" + i + " is 1");
// do something
}
}
See JMeter API - JavaDoc on all JMeter classes and How to Use BeanShell: JMeter's Favorite Built-in Component for more information on how to get started with Beanshell in JMeter