javajmeterjmeter-plugins

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();
        }

Solution

  • 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)