Apache Jmeter is a great versatile tool for performance testing of web servers, DBMS servers etc. It's a pure Java application where you can use even your own Java code to customize and randomize your tests. My intention of this post is not to tell you about all of those features, but one such cool feature of Jmeter which is running Jmeter tests in non-GUI mode.
If you have worked with Jmeter you surely should have experienced that sometimes it get stuck or crashes while you are doing high concurrency (> 300) load testing. One solution for this is to create your test using the GUI and save it as a '.jmx' file and later run that in non-GUI mode and save the test results to a '.jtl' file. In that way you will be able to carry out your load test without crashing or maybe with more concurrency.
OKEY..... This is how to do it.
1. First prepare your test plan with Jmeter and save it, let's say the file name is 'mytest.jmx'. (It gets saved as a xml configuration file with the .jmx extention).
2. Then go to Apache JMETER_HOME/bin folder using command shell. And then run Jmeter with the following parameters, to execute the test.
3. While the test is running the results will be saved in the 'mytest_results.jtl'. When your test is complete you can open this jtl file in Jmeter and summarize the results or create graphs using it.
To do that open Jmeter and add a Summary Report to the test plan (Add --> Listener --> Summary Report). And then go to the Summary Report UI and 'Browse' and open your mytest_results.jtl file.
OK.....next comes the real headache :-). Let's say you have to repeat the above test several times with small changes to the test. I actually had a requirement at my work to repeat the same Jmeter test with different concurrency levels and number of loops.
The hard way to do this is create separate test scripts for different concurrency levels using the GUI and run them separately as above.
A less hard way to do this is open the test file (.jmx) using a text editor and change the values every time you repeat the test, in the ThreadGroup element in the test configuration(as below), and run the same file.
OK.... But why not automate the above 'less hard way' and make your life easy..
If you are a shell scripting master this is a "few lines" work, but since I'm not, this is how I did it.
For newbies like me, I will explain the script briefly.
For this script to work first you should do a small change to your Jmeter test configuration. You have to give a variable string for num_threads and loop instead of actual values, as below.
In the shell script, first I put the concurrency values and loop values in to 2 different arrays.
And then using a while loop I edit the concurrency and loop values in Jmeter test script for each time I have to repeat the test. I have used sed command for that. It searches for the _loop_ and _con_ strings in the Jmeter script and will replace it with the corresponding values in above two arrays.
Then inside the loop, changed Jmeter script is executed (for the number of times the while loop is run) in non GUI mode and results are saved in different jtl files.
If you have worked with Jmeter you surely should have experienced that sometimes it get stuck or crashes while you are doing high concurrency (> 300) load testing. One solution for this is to create your test using the GUI and save it as a '.jmx' file and later run that in non-GUI mode and save the test results to a '.jtl' file. In that way you will be able to carry out your load test without crashing or maybe with more concurrency.
OKEY..... This is how to do it.
1. First prepare your test plan with Jmeter and save it, let's say the file name is 'mytest.jmx'. (It gets saved as a xml configuration file with the .jmx extention).
2. Then go to Apache JMETER_HOME/bin folder using command shell. And then run Jmeter with the following parameters, to execute the test.
./jmeter -n -t \absolute_path\mytest.jmx -l \absolute_path\mytest_results.jtl
3. While the test is running the results will be saved in the 'mytest_results.jtl'. When your test is complete you can open this jtl file in Jmeter and summarize the results or create graphs using it.
To do that open Jmeter and add a Summary Report to the test plan (Add --> Listener --> Summary Report). And then go to the Summary Report UI and 'Browse' and open your mytest_results.jtl file.
OK.....next comes the real headache :-). Let's say you have to repeat the above test several times with small changes to the test. I actually had a requirement at my work to repeat the same Jmeter test with different concurrency levels and number of loops.
The hard way to do this is create separate test scripts for different concurrency levels using the GUI and run them separately as above.
A less hard way to do this is open the test file (.jmx) using a text editor and change the values every time you repeat the test, in the ThreadGroup element in the test configuration(as below), and run the same file.
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">1000</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">300</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<longProp name="ThreadGroup.start_time">1339414812000</longProp>
<longProp name="ThreadGroup.end_time">1339414812000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">1000</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">300</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<longProp name="ThreadGroup.start_time">1339414812000</longProp>
<longProp name="ThreadGroup.end_time">1339414812000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
OK.... But why not automate the above 'less hard way' and make your life easy..
If you are a shell scripting master this is a "few lines" work, but since I'm not, this is how I did it.
#!/bin/bash
i=0
conc[0]=50
conc[1]=100
conc[2]=250
conc[3]=500
conc[4]=750
conc[5]=1000
conc[6]=1250
loop[0]=5000
loop[1]=2500
loop[2]=1000
loop[3]=500
loop[4]=334
loop[5]=250
loop[6]=200
cd ./jmx
while test $i != 7
do
sed 's/_loop_/'${loop[$i]}'/g' mytest.jmx > ./jmtest.jmx
sed 's/_con_/'${conc[$i]}'/g' jmtest.jmx > jmtest_${conc[$i]}.jmx
rm jmtest.jmx
cd ../apache-jmeter-2.6/bin/
./jmeter -n -t ../../jmx/jmtest_${conc[$i]}.jmx -l ../../jtl/results_${conc[$i]}.jtl
i=`expr $i + 1`
cd ../../jmx
done
i=0
conc[0]=50
conc[1]=100
conc[2]=250
conc[3]=500
conc[4]=750
conc[5]=1000
conc[6]=1250
loop[0]=5000
loop[1]=2500
loop[2]=1000
loop[3]=500
loop[4]=334
loop[5]=250
loop[6]=200
cd ./jmx
while test $i != 7
do
sed 's/_loop_/'${loop[$i]}'/g' mytest.jmx > ./jmtest.jmx
sed 's/_con_/'${conc[$i]}'/g' jmtest.jmx > jmtest_${conc[$i]}.jmx
rm jmtest.jmx
cd ../apache-jmeter-2.6/bin/
./jmeter -n -t ../../jmx/jmtest_${conc[$i]}.jmx -l ../../jtl/results_${conc[$i]}.jtl
i=`expr $i + 1`
cd ../../jmx
done
For newbies like me, I will explain the script briefly.
For this script to work first you should do a small change to your Jmeter test configuration. You have to give a variable string for num_threads and loop instead of actual values, as below.
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">_loop_</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">_con_</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<longProp name="ThreadGroup.start_time">1339414812000</longProp>
<longProp name="ThreadGroup.end_time">1339414812000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">_loop_</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">_con_</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<longProp name="ThreadGroup.start_time">1339414812000</longProp>
<longProp name="ThreadGroup.end_time">1339414812000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
In the shell script, first I put the concurrency values and loop values in to 2 different arrays.
And then using a while loop I edit the concurrency and loop values in Jmeter test script for each time I have to repeat the test. I have used sed command for that. It searches for the _loop_ and _con_ strings in the Jmeter script and will replace it with the corresponding values in above two arrays.
Then inside the loop, changed Jmeter script is executed (for the number of times the while loop is run) in non GUI mode and results are saved in different jtl files.
Hi ,
ReplyDeleteThis is really helpful,, can u pls guide me with one my doubt that ,
if I have 3 thread group in my script and i want to run any one of them through CMD , what should be the suntax ..
Waiting for ur reply .
Hi Anukrosh,
DeleteI don't think it is possible to start a selected thread group separately when you have multiple thread groups in one script. There is no command line parameter to support such functionality. Refer "2.4 Running JMeter" section in http://jmeter.apache.org/usermanual/get-started.html
Thanks Nirodha...
DeleteVery Useful, Thanks
ReplyDeleteThanks for the great post. There are some more options on running JMeter without GUI, if anyone is interested check 5 Ways To Launch a JMeter Test without Using the JMeter GUI guide which covers Ant, Maven and programmatic execution/creation of JMeter tests.
ReplyDeletecan anyone help to do performance testing of 500 websites using jmeter in non-gui mode?
ReplyDelete"./" this is the way to execute the *.sh or *.pl scripts in backend on solaris or unix boxes. In order to run JMeter in non-GUI mode we can simply type from command line --> jmeter -n -t \absolute_path\mytest.jmx -l \absolute_path\mytest_results.jtl
ReplyDeletethanks for sharing..
ReplyDeleteHi,
ReplyDeleteI am running the Jmeter in Linux but I have to increase the Jmeter Heap size in linux
please suggest to me
Thanks in advance
i want to create a java application that automatically generates test scripts for jmeter. We pass the url, GET or POST method, expected result like 200 OK or 404 not found, and specify the number of users. The values are passed to jmeter, which is then tested and the status result is passed back to my application.
ReplyDeleteCan anyone please help ?
Great article..thanks for sharing
ReplyDeleteWell, I think your blog is pretty good and have lots of useful information about Jmeter. Keep it up!
ReplyDeleteHi Niro,
ReplyDeleteIs there a way to use Jmeter completely through Java API's.
Sorry for the late reply.
DeletePlease have a look at https://jmeter.apache.org/api/
HI Niro,
ReplyDeleteI have a requirment where the jmx itself has to be created with shell script .Can this be done.
Hi Sailaja,
DeleteI'm not sure about that. However you can use Ant Jmeter plugin to keep parameterized jmeter test templates and use And scripts to pass values and execute the jmeter script. Please check
http://www.programmerplanet.org/projects/jmeter-ant-task/
In your script are you manually running the jmeter-server.bat coz i dont see it invoked in your script.
DeleteHi Niro,
ReplyDeletewhile running Jmeter script in Non GUI mode it is pulling Error,Could not open .jmx file,I tried different paths
Hi Niro, As a part of prep to trigger through jenkins i was trying to run .jmx script locally in non-gui mode. I get few errors as below but later the script ran and got the output in .csv file. Can someone help me resolve the errors:-
ReplyDeleteCommand:-./jmeter -n -t ./examples/Dec21Test.jmx -l ./examples/resultsJan19.csv
Errors:-
main ERROR Null object returned for File in Appenders.
2019-01-20 15:11:46,020 main ERROR Unable to locate appender “jmeter-log” for logger config “root”
Creating summariser
Created the tree successfully using ./examples/Dec21Test.jmx
Starting the test @ Sun Jan 20 15:11:46 CST 2019 (1548018706536)
Waiting for possible Shutdown/StopTestNow/Heapdump message on port 4446
summary + 5 in 00:00:48 = 0.1/s Avg: 1286 Min: 0 Max: 3673 Err: 0 (0.00%) Active: 1 Started: 1 Finished: 0
summary + 2 in 00:00:30 = 0.1/s Avg: 1035 Min: 404 Max: 1667 Err: 0 (0.00%) Active: 1 Started: 1 Finished: 0
summary = 7 in 00:01:18 = 0.1/s Avg: 1214 Min: 0 Max: 3673 Err: 0 (0.00%)
summary + 3 in 00:00:30 = 0.1/s Avg: 473 Min: 1 Max: 1211 Err: 0 (0.00%) Active: 1 Started: 1 Finished: 0
summary = 10 in 00:01:48 = 0.1/s Avg: 992 Min: 0 Max: 3673 Err: 0 (0.00%)
summary + 1 in 00:00:12 = 0.1/s Avg: 426 Min: 426 Max: 426 Err: 0 (0.00%) Active: 0 Started: 1 Finished: 1
summary = 11 in 00:02:00 = 0.1/s Avg: 941 Min: 0 Max: 3673 Err: 0 (0.00%)
Tidying up ... @ Sun Jan 20 15:13:47 CST 2019 (1548018827241)
... end of run
I'm having the same error, did you could solve it?
DeleteWere u able to solve this?
DeleteIt is really helpful article please read it too my blog AVG UI failed to load
ReplyDeleteI am using ubuntu system, so my command is like ./jmeter...., have kept my files in bin folder with name plan [plan.jmx and plan.csv], and tried command with path and direct file name.
ReplyDeletebut always getting 'Could not open plan.jmx'
I made a silly mistake, I did not follow strict capital-small structure for file name in my command. like PLAN, plan, Plan difference.
Delete./jmeter -n -t plan.jmx -l plan.csv
./jmeter -n -t Plan.jmx -l Plan.csv
give commands as per file name exactly.
This is realy a Nice blog post read on of my blogs It is really helpful article please read it too my blog AVG UI Failed To Load. you can visits our websites or toll free no +1-866-558-4555. solve your problem fastly.
ReplyDelete