来自 Java 代码的 JMeter - 如何将 ConstantThroughputTimer 添加到我的测试中
JMeter From Java Code - How to add ConstantThroughputTimer to my Test
我有一个 Class,它演示了来自 Java 代码的 JMeter 测试。
测试对象设置为每秒N次请求
我想在我的测试中添加一个 ConstantThroughputTimer 以设置 JMeter 正在生成的最大 RPS(每秒请求数)。
在 gui 中创建了一个并且运行良好,但我想从 java 代码中 运行 它。
现在我有两个问题:
- 不知道如何设置线程组'loop count'永远。 (见截图)
- 我无法将 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();
}
}
要将 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();
-
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());
有关详细信息,请参阅:
嗯,根据文档:
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;
}
}
我有一个 Class,它演示了来自 Java 代码的 JMeter 测试。
测试对象设置为每秒N次请求
我想在我的测试中添加一个 ConstantThroughputTimer 以设置 JMeter 正在生成的最大 RPS(每秒请求数)。
在 gui 中创建了一个并且运行良好,但我想从 java 代码中 运行 它。
现在我有两个问题:
- 不知道如何设置线程组'loop count'永远。 (见截图)
- 我无法将 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();
}
}
要将 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();
-
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());
有关详细信息,请参阅:
嗯,根据文档:
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;
}
}