英文:
StandardJMeterEngine run method not triggering the HTTPSampler
问题
我正在尝试创建一个Java类,该类可以使用JMeter调用REST API。我这样做是因为我将需要这个工具来创建一种执行某种负载测试的实用程序。
我已经安装了JMeter,并且在GUI模式下,我能够创建并运行能够访问我的API的测试。然后我采用了许多网站上建议的示例代码,并尝试运行相同的代码。
代码如下:
public class JMeterTestRunner {
public static void main(String[] argv) throws Exception {
//JMeter 引擎
StandardJMeterEngine jmeter = new StandardJMeterEngine();
//JMeter 初始化(属性、日志级别、区域设置等)
JMeterUtils.loadJMeterProperties("/Users/something/apache-jmeter-5.2.1/bin/jmeter.properties");
JMeterUtils.initLogging(); // 如果需要查看额外的日志消息,可以将此行注释掉,例如 DEBUG 级别的日志
JMeterUtils.initLocale();
// JMeter 测试计划,基本上都是 JOrphan HashTree
HashTree testPlanTree = new HashTree();
// HTTP 采样器
HTTPSampler httpSampler = new HTTPSampler();
httpSampler.setDomain("localhost");
httpSampler.setPort(8405);
httpSampler.setPath("/some_path");
httpSampler.setMethod("GET");
// 循环控制器
LoopController loopController = new LoopController();
loopController.setLoops(1);
loopController.addTestElement(httpSampler);
loopController.setFirst(true);
loopController.initialize();
// 线程组
ThreadGroup threadGroup = new ThreadGroup();
threadGroup.setNumThreads(1);
threadGroup.setRampUp(1);
threadGroup.setSamplerController(loopController);
// 测试计划
TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
// 从之前初始化的元素构建测试计划
testPlanTree.add("testPlan", testPlan);
testPlanTree.add("loopController", loopController);
testPlanTree.add("threadGroup", threadGroup);
testPlanTree.add("httpSampler", httpSampler);
// 运行测试计划
jmeter.configure(testPlanTree);
jmeter.run();
}
}
现在发生的情况是,这个代码可以正常运行,但是API端点没有被访问到。我已经进行了调试,jmeter的配置看起来完全正常。我得到的输出如下:
(以下是输出的日志内容,由于您只需要翻译代码部分,所以不再重复展示日志内容)
我已经做了一些搜索,并尝试了很多不同链接中提到的建议,比如:
https://stackoverflow.com/questions/31541030/jmeter-api-code-to-run-httpsampler-doesnt-work
但是这些似乎都没有解决我的问题。
我对JMeter还不太了解,所以非常感谢任何帮助。提前谢谢。
英文:
I am trying to create a Java class that can make a call to a REST API using JMeter. I am doing this as I will be needing this to create a utility to do some kind of load testing.
I installed JMeter and using the GUI mode I was able to create and run the test that is able to hit my API. Then I took the sample code suggested on many websites and tried to run the same.
The code is mentioned below:
public class JMeterTestRunner {
public static void main(String[] argv) throws Exception {
//JMeter Engine
StandardJMeterEngine jmeter = new StandardJMeterEngine();
//JMeter initialization (properties, log levels, locale, etc)
JMeterUtils.loadJMeterProperties("/Users/something/apache-jmeter-5.2.1/bin/jmeter.properties");
JMeterUtils.initLogging();// you can comment this line out to see extra log messages of i.e. DEBUG level
JMeterUtils.initLocale();
// JMeter Test Plan, basic all u JOrphan HashTree
HashTree testPlanTree = new HashTree();
// HTTP Sampler
HTTPSampler httpSampler = new HTTPSampler();
httpSampler.setDomain("localhost");
httpSampler.setPort(8405);
httpSampler.setPath("/some_path");
httpSampler.setMethod("GET");
// Loop Controller
LoopController loopController = new LoopController();
loopController.setLoops(1);
loopController.addTestElement(httpSampler);
loopController.setFirst(true);
loopController.initialize();
// Thread Group
ThreadGroup threadGroup = new ThreadGroup();
threadGroup.setNumThreads(1);
threadGroup.setRampUp(1);
threadGroup.setSamplerController(loopController);
// Test Plan
TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
// Construct Test Plan from previously initialized elements
testPlanTree.add("testPlan", testPlan);
testPlanTree.add("loopController", loopController);
testPlanTree.add("threadGroup", threadGroup);
testPlanTree.add("httpSampler", httpSampler);
// Run Test Plan
jmeter.configure(testPlanTree);
jmeter.run();
}
}
Now what happens is this runs fine, but the API endpoint doesn't get hit. I have debugged this and the configuration of the jmeter looks perfectly fine. The output that I get is mentioned below:
2020-04-10 01:11:36 [main] WARN JMeterUtils:732 - Exception 'null' occurred when fetching boolean property:'server.exitaftertest', defaulting to: false
2020-04-10 01:11:36 [main] WARN JMeterUtils:732 - Exception 'null' occurred when fetching boolean property:'jmeterengine.remote.system.exit', defaulting to: false
2020-04-10 01:11:36 [main] WARN JMeterUtils:732 - Exception 'null' occurred when fetching boolean property:'jmeterengine.stopfail.system.exit', defaulting to: true
2020-04-10 01:11:36 [main] WARN JMeterUtils:732 - Exception 'null' occurred when fetching boolean property:'jmeterengine.force.system.exit', defaulting to: false
2020-04-10 01:11:36 [main] INFO JMeterUtils:365 - Setting Locale to en_IN
2020-04-10 01:11:36 [main] INFO HTTPSamplerBase:1465 - Parser for text/html is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2020-04-10 01:11:36 [main] INFO HTTPSamplerBase:1465 - Parser for application/xhtml+xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2020-04-10 01:11:36 [main] INFO HTTPSamplerBase:1465 - Parser for application/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2020-04-10 01:11:36 [main] INFO HTTPSamplerBase:1465 - Parser for text/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2020-04-10 01:11:36 [main] INFO HTTPSamplerBase:1465 - Parser for text/vnd.wap.wml is org.apache.jmeter.protocol.http.parser.RegexpHTMLParser
2020-04-10 01:11:36 [main] INFO HTTPSamplerBase:1465 - Parser for text/css is org.apache.jmeter.protocol.http.parser.CssParser
2020-04-10 01:11:36 [main] INFO HTTPJavaImpl:71 - Maximum connection retries = 0
2020-04-10 01:11:36 [main] INFO StandardJMeterEngine:351 - Running the test!
2020-04-10 01:11:36 [main] INFO SampleEvent:64 - List of sample_variables: []
2020-04-10 01:11:36 [main] INFO SampleEvent:64 - List of sample_variables: []
2020-04-10 01:11:36 [main] INFO CompoundVariable:66 - Note: Function class names must contain the string: '.functions.'
2020-04-10 01:11:36 [main] INFO CompoundVariable:69 - Note: Function class names must not contain the string: '.gui.'
2020-04-10 01:11:36 [main] WARN CompoundVariable:83 - Did not find any functions
2020-04-10 01:11:36 [main] INFO StandardJMeterEngine:450 - Starting ThreadGroup: 1 :
2020-04-10 01:11:36 [main] INFO StandardJMeterEngine:510 - Starting 1 threads for group .
2020-04-10 01:11:36 [main] INFO StandardJMeterEngine:520 - Thread will continue on error
2020-04-10 01:11:36 [main] INFO ThreadGroup:220 - Starting thread group... number=1 threads=1 ramp-up=1 delayedStart=false
2020-04-10 01:11:36 [main] INFO ThreadGroup:246 - Started thread group number 1
2020-04-10 01:11:36 [main] INFO StandardJMeterEngine:461 - All thread groups have been started
2020-04-10 01:11:36 [ 1-1] INFO JMeterThread:711 - Thread started: 1-1
2020-04-10 01:11:36 [ 1-1] INFO JMeterThread:299 - Thread is done: 1-1
2020-04-10 01:11:36 [ 1-1] INFO JMeterThread:328 - Thread finished: 1-1
2020-04-10 01:11:36 [main] INFO StandardJMeterEngine:214 - Notifying test listeners of end of test
2020-04-10 01:11:36 [main] INFO FileServer:87 - Default base='/Users/somepath'
I have done my share of googling and tried many suggestions mentioned on various links such as :
https://stackoverflow.com/questions/31541030/jmeter-api-code-to-run-httpsampler-doesnt-work
But this doesn't seem to address/resolve my issue.
I am new to this Jmeter thing so any help will be most welcome.
Thanks in advance.
答案1
得分: 2
-
Your way of adding the Test Elements to the Test plan is not correct, you need to change it to the following:
testPlanTree.add(testPlan); HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup); threadGroupHashTree.add(httpSampler);
-
You don't seem to store your results anywhere, it would be good to save them into .jtl results file for later analysis like:
Summariser summer = null; String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary"); if (summariserName.length() > 0) { summer = new Summariser(summariserName); } String logFile = "/Users/something/apache-jmeter-5.2.1/bin/result.jtl"; ResultCollector logger = new ResultCollector(summer); logger.setFilename(logFile); testPlanTree.add(testPlanTree.getArray()[0], logger);
-
Having the application under test and the JMeter on the same machine is not the best idea as you won't get reliable test results, consider running JMeter from another host. It would be also a good idea to monitor the essential OS health metrics like CPU, RAM, Network and Disk IO, etc. on both JMeter and system under test sides, it can be done using JMeter PerfMon Plugin
Full code just in case:
public static void main(String[] args) throws IOException {
//JMeter Engine
StandardJMeterEngine jmeter = new StandardJMeterEngine();
//JMeter initialization (properties, log levels, locale, etc)
JMeterUtils.loadJMeterProperties("/Users/something/apache-jmeter-5.2.1/bin/jmeter.properties");
JMeterUtils.initLogging();// you can comment this line out to see extra log messages of i.e. DEBUG level
JMeterUtils.initLocale();
// JMeter Test Plan, basic all u JOrphan HashTree
HashTree testPlanTree = new HashTree();
// HTTP Sampler
HTTPSampler httpSampler = new HTTPSampler();
httpSampler.setDomain("localhost");
httpSampler.setPort(8405);
httpSampler.setPath("/some_path");
httpSampler.setMethod("GET");
httpSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
httpSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
// Loop Controller
LoopController loopController = new LoopController();
loopController.setLoops(1);
loopController.addTestElement(httpSampler);
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.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());
SaveService.saveTree(testPlanTree, new FileOutputStream("/Users/something/apache-jmeter-5.2.1/bin/test.jmx"));
Summariser summer = null;
String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
if (summariserName.length() > 0) {
summer = new Summariser(summariserName);
}
String logFile = "/Users/something/apache-jmeter-5.2.1/bin/result.jtl";
ResultCollector logger = new ResultCollector(summer);
logger.setFilename(logFile);
testPlanTree.add(testPlanTree.getArray()[0], logger);
// Construct Test Plan from previously initialized elements
testPlanTree.add(testPlan);
HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
threadGroupHashTree.add(httpSampler);
// Run Test Plan
jmeter.configure(testPlanTree);
jmeter.run();
}
英文:
-
Your way of adding the Test Elements to the Test plan is not correct, you need to change it to the following:
testPlanTree.add(testPlan); HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup); threadGroupHashTree.add(httpSampler);
-
You don't seem to store your results anywhere, it would be good to save them into .jtl results file for later analysis like:
Summariser summer = null; String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary"); if (summariserName.length() > 0) { summer = new Summariser(summariserName); } String logFile = "/Users/something/apache-jmeter-5.2.1/bin/result.jtl"; ResultCollector logger = new ResultCollector(summer); logger.setFilename(logFile); testPlanTree.add(testPlanTree.getArray()[0], logger);
-
Having the application under test and the JMeter on the same machine is not the best idea as you won't get reliable test results, consider running JMeter from another host. It would be also a good idea to monitor the essential OS health metrics like CPU, RAM, Network and Disk IO, etc. on both JMeter and system under test sides, it can be done using JMeter PerfMon Plugin
Full code just in case:
public static void main(String[] args) throws IOException {
//JMeter Engine
StandardJMeterEngine jmeter = new StandardJMeterEngine();
//JMeter initialization (properties, log levels, locale, etc)
JMeterUtils.loadJMeterProperties("/Users/something/apache-jmeter-5.2.1/bin/jmeter.properties");
JMeterUtils.initLogging();// you can comment this line out to see extra log messages of i.e. DEBUG level
JMeterUtils.initLocale();
// JMeter Test Plan, basic all u JOrphan HashTree
HashTree testPlanTree = new HashTree();
// HTTP Sampler
HTTPSampler httpSampler = new HTTPSampler();
httpSampler.setDomain("localhost");
httpSampler.setPort(8405);
httpSampler.setPath("/some_path");
httpSampler.setMethod("GET");
httpSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
httpSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
// Loop Controller
LoopController loopController = new LoopController();
loopController.setLoops(1);
loopController.addTestElement(httpSampler);
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.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());
SaveService.saveTree(testPlanTree, new FileOutputStream("/Users/something/apache-jmeter-5.2.1/bin/test.jmx"));
Summariser summer = null;
String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
if (summariserName.length() > 0) {
summer = new Summariser(summariserName);
}
String logFile = "/Users/something/apache-jmeter-5.2.1/bin/result.jtl";
ResultCollector logger = new ResultCollector(summer);
logger.setFilename(logFile);
testPlanTree.add(testPlanTree.getArray()[0], logger);
// Construct Test Plan from previously initialized elements
testPlanTree.add(testPlan);
HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
threadGroupHashTree.add(httpSampler);
// Run Test Plan
jmeter.configure(testPlanTree);
jmeter.run();
}
答案2
得分: 0
我发现了一个问题。当向接口传递参数时,只能传递 String 类型的参数,而不能传递 Int 类型的参数。怎么办?
public static HTTPSamplerProxy createHTTPSamplerProxy() {
HeaderManager headerManager = new HeaderManager();
headerManager.setProperty("Content-Type", "multipart/form-data");
headerManager.add(new Header("token","****"));
HTTPSamplerProxy httpSamplerProxy = new HTTPSamplerProxy();
httpSamplerProxy.setHeaderManager(headerManager);
httpSamplerProxy.setDomain("localhost");
httpSamplerProxy.setPort(7081);
httpSamplerProxy.setPath("/somepath");
httpSamplerProxy.setMethod("GET");
httpSamplerProxy.setConnectTimeout("5000");
Arguments arguments = new Arguments();
httpSamplerProxy.addNonEncodedArgument("page","1","1");
httpSamplerProxy.addNonEncodedArgument("pageNum","1","1");
httpSamplerProxy.setUseKeepAlive(true);
httpSamplerProxy.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
httpSamplerProxy.setHeaderManager(headerManager);
return httpSamplerProxy;
}
英文:
I found a problem. When passing parameters to the interface, only parameters of type String can be passed, and parameters of type Int cannot be passed. How to do this?
public static HTTPSamplerProxy createHTTPSamplerProxy() {
HeaderManager headerManager = new HeaderManager();
headerManager.setProperty("Content-Type", "multipart/form-data");
headerManager.add(new Header("token","****"));
HTTPSamplerProxy httpSamplerProxy = new HTTPSamplerProxy();
httpSamplerProxy.setHeaderManager(headerManager);
httpSamplerProxy.setDomain("localhost");
httpSamplerProxy.setPort(7081);
httpSamplerProxy.setPath("/somepath");
httpSamplerProxy.setMethod("GET");
httpSamplerProxy.setConnectTimeout("5000");
Arguments arguments = new Arguments();
httpSamplerProxy.addNonEncodedArgument("page","1","1");
httpSamplerProxy.addNonEncodedArgument("pageNum","1","1");
httpSamplerProxy.setUseKeepAlive(true);
httpSamplerProxy.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
httpSamplerProxy.setHeaderManager(headerManager);
return httpSamplerProxy;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论