StandardJMeterEngine的run方法未触发HTTPSampler。

huangapple go评论73阅读模式
英文:

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

  1. 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);
    
  2. 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);
    
  3. 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();
}
英文:
  1. 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);
    
  2. 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);
    
  3. 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;
}

huangapple
  • 本文由 发表于 2020年4月10日 04:06:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/61129378.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定