FeeLGooD
FeeLGooD

Reputation: 505

Dynamically set user defined variable

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

Answers (2)

Keet Sugathadasa
Keet Sugathadasa

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

Dmitri T
Dmitri T

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

Related Questions