Reputation: 505
Is there any way to dynamically set the user defined variable within the jmx file during the startup of the test by using Java?
So far I am able to print the name by using this code:
try {
// JMeter Engine
StandardJMeterEngine jmeter = new StandardJMeterEngine();
// Initialize Properties, logging, locale, etc.
JMeterUtils.loadJMeterProperties("c:\\path\\jmeter.properties");
JMeterUtils.setJMeterHome("C:\\path\\apache-jmeter-5.0");
JMeterUtils.initLocale();
// Initialize JMeter SaveService
SaveService.loadProperties();
// Load existing .jmx Test Plan
Path path = Paths.get("C:\\path\\whatever.jmx");
HashTree testPlanTree = SaveService.loadTree(path.toFile());
// Run JMeter Test
jmeter.configure(testPlanTree);
JMeterTreeModel treeModel = new JMeterTreeModel();
JMeterTreeNode root = (JMeterTreeNode) treeModel.getRoot();
treeModel.addSubTree(testPlanTree, root);
SearchByClass<TestPlan> testPlan = new SearchByClass<>(TestPlan.class);
testPlanTree.traverse(testPlan);
Collection<TestPlan> testPlans = testPlan.getSearchResults();
for (TestPlan testPlan1 : testPlans) {
System.out.println(testPlan1.getName());
JMeterProperty udvProperty = testPlan1.getUserDefinedVariablesAsProperty();
Arguments arg = (Arguments) udvProperty.getObjectValue();
CollectionProperty arguments = arg.getArguments();
arguments.forEach(c -> {
System.out.println(c);
});
}
// jmeter.run();
}
catch (IOException | IllegalUserActionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I am almost there! But just need some suggestions of whether this is the correct direction to go? Or there is another better approach?
Update: I am able to set the variable by modify above code to:
try {
// JMeter Engine
StandardJMeterEngine jmeter = new StandardJMeterEngine();
// Initialize Properties, logging, locale, etc.
JMeterUtils.loadJMeterProperties("c:\\path\\jmeter.properties");
JMeterUtils.setJMeterHome("C:\\path\\apache-jmeter-5.0");
JMeterUtils.initLocale();
// Initialize JMeter SaveService
SaveService.loadProperties();
// Load existing .jmx Test Plan
Path path = Paths.get("C:\\path\\whatever.jmx");
HashTree testPlanTree = SaveService.loadTree(path.toFile());
// Run JMeter Test
jmeter.configure(testPlanTree);
JMeterTreeModel treeModel = new JMeterTreeModel();
JMeterTreeNode root = (JMeterTreeNode) treeModel.getRoot();
treeModel.addSubTree(testPlanTree, root);
SearchByClass<TestPlan> testPlan = new SearchByClass<>(TestPlan.class);
testPlanTree.traverse(testPlan);
Collection<TestPlan> testPlans = testPlan.getSearchResults();
for (TestPlan testPlan1 : testPlans) {
System.out.println(testPlan1.getName());
JMeterProperty udvProperty = testPlan1.getUserDefinedVariablesAsProperty();
Arguments arg = (Arguments) udvProperty.getObjectValue();
CollectionProperty arguments = arg.getArguments();
arguments.forEach(c -> {
Argument j = (Argument) c.getObjectValue();
System.out.println("-----j--- " + j.getName());
j.setValue("whatever value");
System.out.println(j);
});
}
// jmeter.run();
}
catch (IOException | IllegalUserActionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Upvotes: 2
Views: 2849
Reputation: 13502
After careful research, I came up with this code snippet. I have tested this on JMeter versions 5.3 and above and it works for me. It looks similar to the other answers, but I have carefully explained what's happening in each line. Hope this helps.
// Initialize Properties, logging, locale, etc.
JMeterUtils.loadJMeterProperties("apache-jmeter-5.3/bin/jmeter.properties");
JMeterUtils.setJMeterHome("apache-jmeter-5.3"); // Have the apache JMeter extracted in the same folder
JMeterUtils.initLocale();
try {
// Initialize JMeter SaveService
SaveService.loadProperties();
} catch (IOException e) {
// handle the error
}
// add user defined variables
HashMap<String, String> userArguments = new HashMap<>();
userArguments.put("variable1", "value1");
userArguments.put("variable2", "value2");
userArguments.put("variable3", "value3");
String jmxFilePath = "jmeterscript.jmx";
File jmxFile = new File(jmxFilePath);
// get the jmeter to run by configuring it
StandardJMeterEngine jMeterEngine = configureJmeterEngine(jmxFile, userArguments);
// starting to invoke the JMeter Script
jMeterEngine.run();
jMeterEngine.reset();
jMeterEngine.exit();
/**
* This method returns a configured StandardJMeterEngine based on a arguments configured in
* a JMX file and arguments defined by user through metadata
*
* @param jmxFileName JMX file path
* @param arguments User defined arguments
* @return Configured StandardJMeterEngine
*/
private StandardJMeterEngine configureJmeterEngine(File jmxFileName, HashMap<String, String> arguments) {
StandardJMeterEngine standardJMeterEngine = new StandardJMeterEngine();
try {
// Get test plan tree
HashTree testPlanTree = SaveService.loadTree(jmxFileName);
// Get all user defined arguments in JMX file
SearchByClass<Arguments> udvSearch = new SearchByClass<>(Arguments.class);
testPlanTree.traverse(udvSearch);
Collection<Arguments> udvs = udvSearch.getSearchResults();
Arguments args = udvs.stream().findAny().orElseGet(Arguments::new);
// Add user defined arguments in metadata
arguments.keySet().forEach(key -> args.addArgument(key, arguments.get(key)));
// Configure JMeter engine
standardJMeterEngine.configure(testPlanTree);
} catch (Exception e) {
logger.error("Error in configuring a Jmeter Probe", e);
}
return standardJMeterEngine;
}
Upvotes: 0
Reputation: 168002
User Defined Variables test element is represented by org.apache.jmeter.config.Arguments class so it makes sense to directly look up for Arguments as it will be more convenient, fast and readable.
There is addArgument() function which can be used for adding an User Defined Variable
For example this code will read the test plan from defined location, add a User Defined Variable foo
with the value of bar
and save the Test Plan back
// JMeter Engine
StandardJMeterEngine jmeter = new StandardJMeterEngine();
// Initialize Properties, logging, locale, etc.
JMeterUtils.loadJMeterProperties("c:\\path\\jmeter.properties");
JMeterUtils.setJMeterHome("C:\\path\\apache-jmeter-5.0");
JMeterUtils.initLocale();
// Initialize JMeter SaveService
SaveService.loadProperties();
// Load existing .jmx Test Plan
Path path = Paths.get("C:\\path\\whatever.jmx");
HashTree testPlanTree = SaveService.loadTree(path.toFile());
SearchByClass<Arguments> udvSearch = new SearchByClass<>(Arguments.class);
testPlanTree.traverse(udvSearch);
Collection<Arguments> udvs = udvSearch.getSearchResults();
Arguments userDefinedVariables = udvs.stream().findAny().get();
System.out.println("Current values:");
userDefinedVariables.getArgumentsAsMap().forEach((k, v) -> System.out.println("Name : " + k + " Value : " + v));
userDefinedVariables.addArgument("foo", "bar");
SaveService.saveTree(testPlanTree, new FileOutputStream("C:\\path\\whatever.jmx"));
Check out Five Ways To Launch a JMeter Test without Using the JMeter GUI for more information regarding different ways of creating a JMeter test plan (including running an existing test and creating a brand new one using JMeter API)
Upvotes: 2