来自 Java 代码的 JMeter - 如何将 ConstantThroughputTimer 添加到我的测试中

JMeter From Java Code - How to add ConstantThroughputTimer to my Test

我有一个 Class,它演示了来自 Java 代码的 JMeter 测试。

测试对象设置为每秒N次请求

我想在我的测试中添加一个 ConstantThroughputTimer 以设置 JMeter 正在生成的最大 RPS(每秒请求数)。

在 gui 中创建了一个并且运行良好,但我想从 java 代码中 运行 它。

现在我有两个问题:

  1. 不知道如何设置线程组'loop count'永远。 (见截图)
  2. 我无法将 ConstantThroughputTimer 添加到我的测试计划中。

我搜索过,但找不到任何关于它的文档,也找不到代码示例。

非常感谢任何帮助。

我的代码:

public static void main(String[] args) {
    StandardJMeterEngine jMeterEngine = new StandardJMeterEngine();
    //Setting JMeter Properties
    File properties = JmeterUtils.getPropertiesFile();
    File home = JmeterUtils.getHomePath();
    JMeterUtils.setJMeterHome(home.getPath());
    JMeterUtils.loadJMeterProperties(properties.getPath());
    JMeterUtils.initLocale();

    //Creating HashTreeTestPlan
    HashTree testPlanTree = new HashTree();

    //Creating HttpSampler
    HTTPSamplerProxy sampler = new HTTPSamplerProxy();
    sampler.setMethod("GET");
    sampler.setDomain("example.com");
    sampler.setUseKeepAlive(true);
    sampler.setFollowRedirects(true);
    sampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
    sampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
    sampler.setEnabled(true);

    //Creating LoopController
    LoopController loopController = new LoopController();
    loopController.setContinueForever(true);
    loopController.setLoops(10000);
    loopController.setFirst(true);
    loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
    loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
    loopController.initialize();
    loopController.setEnabled(true);

    //Creating the number of Threads (clients)
    ThreadGroup threadGroup = new ThreadGroup();
    threadGroup.setName("threadGroup");
    threadGroup.setNumThreads(10);
    threadGroup.setScheduler(true);
    threadGroup.setRampUp(0);
    threadGroup.setDuration(60);
    threadGroup.setSamplerController(loopController);
    threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
    threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
    threadGroup.setEnabled(true);



    //Adding Constant Throughput Timer - This is what i want to add
    ConstantThroughputTimer timer = new ConstantThroughputTimer();
    timer.setProperty(TestElement.TEST_CLASS, ConstantThroughputTimer.class.getName());
    timer.setName("constantTimer");
    double rpsCalc = 10 * 60;
    timer.setThroughput(rpsCalc);
    timer.setEnabled(true);
    timer.setCalcMode(2);


    //NOT WORKING// 
    //NOT WORKING// 
    threadGroup.addTestElement(timer);



    //Test Plan
    TestPlan testPlan = new TestPlan("Test Plan");
    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);

    jMeterEngine.configure(testPlanTree);

    try {
        jMeterEngine.runTest();
    } catch (JMeterEngineException e) {
        e.printStackTrace();
    }
}
  1. 要将 Thread Group 永远配置为 运行:

    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();    
    
  2. 配置Constant Throughput Timer:

    ConstantThroughputTimer ctt = new ConstantThroughputTimer();
    ctt.setName("Constant Throughput Timer");
    ctt.setProperty("throughput", 60 * 10);
    ctt.setProperty("calcMode", 2);
    ctt.setCalcMode(2);
    ctt.setProperty(TestElement.TEST_CLASS, ConstantThroughputTimer.class.getName());
    ctt.setProperty(TestElement.GUI_CLASS, TestBeanGUI.class.getName());
    
  3. 有关详细信息,请参阅:

嗯,根据文档:

Timers are only processed in conjunction with a sampler. A timer which is not in the same scope as a sampler will not be processed at all.

因为你只有一个采样器,而你实际上需要在它上面应用这个计时器,那么

To apply a timer to a single sampler, add the timer as a child element of the sampler. The timer will be applied before the sampler is executed. To apply a timer after a sampler, either add it to the next sampler, or add it as the child of a Test Action Sampler.

也许试试这个?我的意思是,将计时器直接添加到采样器中。

PS 虽然它 看起来 对我来说已经合法,至少在通常的 JMeter GUI 角度来看是这样。不确定是什么问题。

PPS 我想,如果您真的致力于解决问题,可以在这里做些什么 - 您可以将您的计划保存为 .jmx,然后在 JMeter GUI 中执行相同的操作 - 并进行比较。

完整的解决方案

我的运行方法

public void run(String domain, int rps, int durationInSeconds, String host){
    StandardJMeterEngine jMeterEngine = new StandardJMeterEngine();

    //Setting JMeter Properties
    File properties = JmeterUtils.getPropertiesFile();
    File home = JmeterUtils.getHomePath();
    JMeterUtils.setJMeterHome(home.getPath());
    JMeterUtils.loadJMeterProperties(properties.getPath());
    JMeterUtils.initLocale();

    //Creating HashTreeTestPlan
    HashTree testPlanTree = new HashTree();

    //Creating HttpSampler
    HTTPSamplerProxy httpSamplerProxy = JmeterUtils.createHttpSamplerGet(domain);

    //Creating Header Manager
    HeaderManager headerManager = JmeterUtils.createHeaderManager(host);

    //Creating LoopController
    LoopController loopController = JmeterUtils.createLoopController(-1, true);

    //Creating the number of Threads (clients)
    ThreadGroup threadGroup = JmeterUtils.createThreadGroup(domain, rps, durationInSeconds, loopController);

    //Adding Request Manager To requests HashTree
    HashTree requestHashTree = new HashTree();
    requestHashTree.add(httpSamplerProxy, headerManager);

    //Creating Throughput Timer - Controls the RPS
    ConstantThroughputTimer timer = JmeterUtils.createTimer(rps);

    //Creating Test Plan
    TestPlan testPlan = JmeterUtils.createTestPlan(domain);

    // Construct Test Plan from previously initialized elements
    testPlanTree.add(testPlan);
    HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
    threadGroupHashTree.add(requestHashTree);
    threadGroupHashTree.add(timer);

    //Configuring the Engine & Running the Test
    jMeterEngine.configure(testPlanTree);
    jMeterEngine.runTest();

}

我的 JmeterUtils

public class JmeterUtils {

private static final File PROPERTIES_FILE = new File(System.getProperty("user.dir") + "/testdata/JMeter/bin/jmeter.properties");
private static final File HOME_PATH = new File(System.getProperty("user.dir") + "/testdata/JMeter");

static HeaderManager createHeaderManager(String host){
    HeaderManager headerManager = new HeaderManager();
    if(host != null){
        headerManager.add(new Header("Host",host));
    }
    headerManager.add(new Header("Connection", "Close"));
    headerManager.add(new Header("Cache-Control", "max-age=0"));
    headerManager.add(new Header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52 Safari/536.5"));
    headerManager.setProperty(TestElement.TEST_CLASS, HeaderManager.class.getName());
    headerManager.setProperty(TestElement.GUI_CLASS, HeaderPanel.class.getName());
    headerManager.setEnabled(true);
    return headerManager;
}

static HTTPSamplerProxy createHttpSamplerGet(String domain){
    HTTPSamplerProxy sampler = new HTTPSamplerProxy();
    sampler.setMethod("GET");
    sampler.setDomain(domain);
    sampler.setUseKeepAlive(true);
    sampler.setFollowRedirects(true);
    sampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
    sampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
    sampler.setEnabled(true);
    return sampler;
}

static ThreadGroup createThreadGroup(String name, int numOfThreads, int durationInSeconds, LoopController loopController){
    ThreadGroup threadGroup = new ThreadGroup();
    threadGroup.setName(name);
    threadGroup.setNumThreads(numOfThreads);
    threadGroup.setScheduler(true);
    threadGroup.setRampUp(0);
    threadGroup.setDuration(durationInSeconds);
    threadGroup.setSamplerController(loopController);
    threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
    threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
    threadGroup.setEnabled(true);

    return threadGroup;
}

static LoopController createLoopController(int numOfLoops,boolean continueForever){
    LoopController loopController = new LoopController();
    if(continueForever){
        loopController.setLoops(-1);
    }
    else{
        loopController.setLoops(numOfLoops);
    }
    loopController.setFirst(true);
    loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
    loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
    loopController.initialize();
    loopController.setEnabled(true);

    return loopController;
}

static ConstantThroughputTimer createTimer(int rps){
    ConstantThroughputTimer timer = new ConstantThroughputTimer();
    long rpsCalc = rps * 60;
    timer.setProperty("throughput", rpsCalc);
    timer.setProperty("calcMode", 2);
    timer.setCalcMode(2);
    timer.setThroughput(rpsCalc);
    timer.setEnabled(true);
    timer.setProperty(TestElement.TEST_CLASS, ConstantThroughputTimer.class.getName());
    timer.setProperty(TestElement.GUI_CLASS, TestBeanGUI.class.getName());
    return timer;
}

static TestPlan createTestPlan(String domain){
    TestPlan testPlan = new TestPlan("Traffic Generator\t[" + domain + "]");
    testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
    testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
    testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());
    return testPlan;
}


static File getPropertiesFile(){
    return PROPERTIES_FILE;
}
static File getHomePath(){
    return HOME_PATH;
}

}