Tuesday 17 May 2016

JMeter Non-GUI Mode

You might want to run JMeter in non-GUI mode if you're running distributed tests or if you want to minimise the overhead on your test execution machine. You would use the GUI when you're preparing your scripts and configuring your test plan and when you're running a light load performance test but for heavy load you might consider running in non-GUI mode.

The following command line options are available:

-n - Run in non-GUI mode
-t - Name of the Test Plan jmx file to execute
-l - Name of the JTL file to which log results to
-j - Name of the JMeter run log file
-r - Runs the test remotely on the servers listed in the remote_hosts property
-R - Runs the test remotely on the specified servers

As an example:

jmeter.bat -n -t StressTest.jmx -l StressTestResults.jtl -r


If you're operating behind a firewall then you may need to configure JMeter to work with it. You can use the following command line options to configure the proxy settings:

-H - The proxy server name
-P - The proxy port
-u - A username if the proxy is secured
-a - The password of the user if the proxy is secured

As an example:

jmeter.bat -H some.proxyserver -P 8090 -u ProxyUser -a ProxyPassword

JMeter Base64 Encoding

In the application that I was tasked with testing, the login request was a standard HTTP request with the following properties:

Request Type:
POST

Request URL:
https://someserver/user/login

Request Body:
grant_type=client_credentials&scope=PREPRODUCTION

Headers:
Authorization: Base <Base64 encoded string of ClientID:ClientPassword>
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

The ClientID and ClientPassword variables had to be sent as a header to the server after being Base64 encoded. There are two methods for achieving this:

1. BeanShell PreProcessor

To begin I created the skeleton of my test plan with the components as follows:
In 'User Defined Variables' I created variables for the ClientID and ClientPassword:

In the BeanShell PreProcessor the following code was used:

import org.apache.commons.codec.binary.Base64;


log.info("Base64 Encoding ClientID & ClientPassword");


//Create the complete string which needs to be encoded
String forEncoding = vars.get("ClientID") + ":" + vars.get("ClientPassword");


log.info("forEncoding: " + forEncoding);


//Encode the string
byte[] encoded_ClientCredentials = Base64.encodeBase64(forEncoding.getBytes());


//Save the encoded byte array into a String Variable
vars.put("encoded_ClientCredentials", new String(encoded_ClientCredentials));


log.info("encoded_ClientCredentials: " + vars.get("encoded_ClientCredentials"));

Now in the header, the new encoded variable 'encoded_ClientCredentials' can be used:


2. Custom JMeter Function

Using this method you must have the JMeter Plug-ins installed from http://jmeter-plugins.org/. It uses the JMeter custom function base64Encode, the specification of which can be found here http://jmeter-plugins.org/wiki/Functions/.

The BeanShell PreProcessor is not needed in this method and so can be removed from the TestPlan. The HTTP Header Manager needs to be modified so that the Authorization header value is as follows:

Basic ${__base64Encode(${ClientID}:${ClientPassword})}