I've created a simple test plan in GUI mode, it contains 3 HTTP requests and "Create cart" response contains "id" that I need to pass as a path param to the request of "Update cart".
I've used the JSON extractor to extract and store this variable and in GUI mode everything works just fine. I access the variable via ${token}
The issue I have - I don't know how to extract, store and access the stored variable from the java code. I played around with JsonPostProcessor but seems like I use it incorrectly.
Kindly see the code below:
...
HashTree testPlanContainer = new HashTree();
HeaderManager headerManager = new HeaderManager();
headerManager.add(new Header("Authorization", "Bearer " + token));
headerManager.setProperty(TestElement.TEST_CLASS, HeaderManager.class.getName());
headerManager.setProperty(TestElement.GUI_CLASS, HeaderPanel.class.getName());
HTTPSampler createCustomer = new HTTPSampler();
...set domain, method, body, etc
HTTPSampler createCart = new HTTPSampler();
...set domain, method, body, etc
JSONPostProcessor jsonPostProcessor = new JSONPostProcessor();
jsonPostProcessor.setRefNames("cart-id");
jsonPostProcessor.setJsonPathExpressions("$.id");
jsonPostProcessor.process();
HashTree composeCreateCartWithJsonExtractor = new HashTree();
composeCreateCartWithJsonExtractor.add(createCart, jsonPostProcessor);
HTTPSampler updateCart = new HTTPSampler();
updateCart.setPath("path" + ${cart-id}); //how can I access this variable from java code?
... set domain, method, body, etc
LoopController loopController = new LoopController();
... set details
SetupThreadGroup threadGroup = new SetupThreadGroup();
... set details
TestPlan testPlan = new TestPlan("My test plan");
...set details
testPlanContainer.add(testPlan);
HashTree composer = testPlanContainer.add(testPlan, threadGroup);
composer.add(headerManager);
composer.add(createCustomer);
composer.add(composeCreateCartWithJsonExtractor);
composer.add(updateCart);
SaveService.saveTree(testPlanContainer, new FileOutputStream("src/main/resources/jmxFile.jmx"));
Summariser summariser = new Summariser("summaryOfResults");
ResultCollector resultCollector = new ResultCollector(summariser);
...
testPlanContainer.add(testPlanContainer.getArray()[0], resultCollector);
...
I believe my mistake is somewhere around the JsonPostProcessor, maybe I should use another class or another way how to extract, store and invoke data from one request to another. Will appreciate any advice
It is impossible to help you without seeing your set details
implementation, in order to add JSON Extractor as a child of a Sampler you need to add both to a HashTree, then add this HashTree to the Thread Group's HashTree, add Thread Group's HashTree to Test Plan's HashTree, etc.
Example minimal working code would be something like:
// JMeter Test Plan, basically JOrphan HashTree
HashTree testPlanTree = new HashTree();
// First HTTP Sampler - open jsonplaceholder.typicode.com and extract id
HTTPSamplerProxy jsonplaceholderSampler = new HTTPSamplerProxy();
jsonplaceholderSampler.setDomain("jsonplaceholder.typicode.com");
jsonplaceholderSampler.setPort(80);
jsonplaceholderSampler.setPath("/todos/1");
jsonplaceholderSampler.setMethod("GET");
jsonplaceholderSampler.setName("HTTP Request - get id");
jsonplaceholderSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
jsonplaceholderSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
JSONPostProcessor jsonPostProcessor = new JSONPostProcessor();
jsonPostProcessor.setName("JSON Extractor");
jsonPostProcessor.setProperty("JSONPostProcessor.referenceNames", "cart-id");
jsonPostProcessor.setProperty("JSONPostProcessor.jsonPathExprs", "$.id");
jsonPostProcessor.setProperty(TestElement.TEST_CLASS, JSONPostProcessor.class.getName());
jsonPostProcessor.setProperty(TestElement.GUI_CLASS, JSONPostProcessorGui.class.getName());
// Second HTTP Sampler - open example com
HTTPSamplerProxy exampleComSampler = new HTTPSamplerProxy();
exampleComSampler.setDomain("example.com");
exampleComSampler.setPort(80);
exampleComSampler.setPath("/${cart-id}");
exampleComSampler.setMethod("GET");
exampleComSampler.setName("HTTP Request - send id");
exampleComSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
exampleComSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
// Loop Controller
LoopController loopController = new LoopController();
loopController.setLoops(1);
loopController.setFirst(true);
loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
loopController.initialize();
// Thread Group
ThreadGroup threadGroup = new ThreadGroup();
threadGroup.setName("Example Thread Group");
threadGroup.setNumThreads(1);
threadGroup.setRampUp(1);
threadGroup.setSamplerController(loopController);
threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
// Test Plan
TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());
// Construct Test Plan from previously initialized elements
testPlanTree.add(testPlan);
HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
HashTree firstSamplerHashTree = new HashTree();
firstSamplerHashTree.add(exampleComSampler);
firstSamplerHashTree.add(jsonplaceholderSampler, jsonPostProcessor);
threadGroupHashTree.add(firstSamplerHashTree);
Check out Five Ways To Launch a JMeter Test without Using the JMeter GUI article for general information, you can also find some hints and code snippets in the comments section.
If you're not too comfortable with writing Java code using JMeter API it might be easier to consider using Taurus tool which provides possibility to build JMeter test plans programmatically using simple YAML syntax.