ajax jmeter,How to Load Test AJAX/XHR Enabled Sites With JMeter

It’s hard to find a website or application which doesn’t use Asynchronous JavaScript And XML. Or, as you probably know it: AJAX.

AJAX enables the asynchronous data exchange of the client-server without interfering with the web page. It lets you update certain areas of the page without needing to reload it entirely. AJAX was developed in late 90s by Microsoft, and started getting picked up by major IT companies in the 2000s. It became the de-facto W3C standard in 2006 upon publication of the first draft of the XMLHttpRequest (XHR) documentation

As AJAX is so widely used, it’s important to know how to work with it. In this blog post, I’m going to show you how to use JMeter to performance test AJAX-enabled web sites.

Overcoming the Challenges of Using JMeter With AJAX

A well-known limitation of the fact that JMeter isn’t a browser is its inability to execute Javascript. This means that AJAX calls aren’t automatically executed when JMeter loads a web page. Requests can still be recorded using JMeter’s built in proxy but they’re stored as individual samplers - which is not how AJAX requests work.

For example, let’s say we have a Liferay Portal with the following three portlets:

35e5313bd04ae0f68ccc927f7b46fb6a.png

Red Rectangle = The currency converter

Amber Rectangle = The RSS feed

Blue Rectangle = The iFrame with BlazeMeter website

Now let’s see what happens when we open the Liferay home page with these three portlets. Note: I’ll be using the Firefox browser and the Firebug extension to inspect the AJAX/XHR requests.

7092d848261319cc32269d98581b4dd2.png

As you can see in the above image, three XHR requests are being sent: one for the Currency Converter, another for the RSS and the final one for the Blazemeter site in iFrame.

We’re interested in the first two requests here as JMeter can get the content from  iFrames.

Go to “Retrieve All Embedded Resources from HTML Files” in HTTP Request Defaults and set it to “true”.

Now look at the timeline section. Here you can see that the Currency Converter and RSS requests all started at the same time and in parallel. To replicate this behaviour, you’ll need to execute the following steps:

GET Request to /web/blazemeter/home

AJAX POST request to Currency Converter

AJAX POST request to RSS

Points two and three should be done at the same time using two threads. If the page you’re testing is sending 10 requests, you’ll need to send 10 requests in parallel using 10 threads.

In other words, you’ll need to execute the main GET request by one thread, followed by two POST requests by two parallel threads.

Up to now, JMeter hasn’t provided a sampler which can override thread group settings. So, if you want to run performance tests of AJAX-enabled pages, you have three options:

Use the JMeter WebDriver Sampler to measure page response times with a real browser. It can combined with a JMeter load test to monitor page response times when a web application is experiencing severe load.

Add a JSR223 Sampler with custom code to kick off parallel requests to specific URLs

Develop a custom Sampler capable of spawning extra threads to send requests to AJAX endpoints

We’ve already covered how to use the JMeter WebDriver Sampler in a previous blog post. Click here to read it now.

So, for the rest of this article, I’m going to focus on how you can simulate an AJAX Request with the JSR223 Sampler and develop a custom Sampler.

How to Simulate an AJAX Request with the JSR223 Sampler

I normally encourage JMeter and Blazemeter users to avoid scripting whenever possible. It’s better to use JMeter components and functions instead of reinventing the wheel - but sometimes scripting is a necessary evil.

When you literally can’t proceed without scripting, make sure you choose the most efficient way of getting things done. For something light, go with Beanshell. If your script is doing “heavy” things, opt for the JSR223 Sampler and Groovy language (take a look at the JMeter Performance and Tuning Tips guide for more info on this).

Groovy is the best choice for the JSR223 Sampler language because Groovy’s scripting engine has a compilable interface - meaning it will perform almost as good as a Java code. See Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! for comparison benchmarks, instructions on how to install Groovy and best practices of Groovy scripting.

For this demo, I’m going to execute two concurrent calls to http://example.com and http://blazemeter.com endpoints.  Let’s start with the following Test Plan structure:

Test Plan

Thread Group (all defaults, 1 user, 1 second ramp-up, 1 loop)

JSR223 Sampler

View Results Tree Listener

Populate JSR223 Sampler as follows:

Language: Groovy

Parameters: http://example.com http://blazemeter.com

Script: See the code below:

import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.HttpClient;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.DefaultHttpClient;

import org.apache.http.util.EntityUtils;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors; // necessary imports

List urls = new ArrayList(); // initialize array of URLs

Collections.addAll(urls,args); // read URLs from "Parameters" input and add them to array

ExecutorService pool = Executors.newFixedThreadPool(urls.size()); // initialize pool of Future Tasks with number of threads equal to size of URLs provided

for (String url : urls) { // for each URL from list

final String currentURL = url;

pool.submit(new Runnable() { // Sumbit a new thread which will execute GET request

@Override

public void run() {

try {

HttpClient client = new DefaultHttpClient(); // Use Apache Commons HTTPClient to perform GET request

HttpGet get = new HttpGet(currentURL);

HttpResponse response = client.execute(get);

HttpEntity entity = response.getEntity();

EntityUtils.consume(entity);

} catch (Exception ex) {

ex.printStackTrace();

}

}

});

}

pool.shutdown(); // shut down thread pool

So, the JSR223 Sampler GUI should look like the screenshot below:

acf2f1176c9b8c372e1811268947426e.png

To make sure that everything will work as you expect, catch requests with the Wireshark sniffer tool.

64b4a74ecc22068db1d9eb5c368693cf.png

As you can see, both requests start asynchronously. JMeter follows pretty much the same behaviour here as real browsers with AJAX requests.

2e03ee5d9b0177e4ce28a7d784bff7df.png

So, when running JSR223 Sampler AJAX request simulations, your Test Plan should look like this:

Test Plan

Thread Group

Transaction Contoller

Main Request

JSR223 Sampler

….

You’ll need the Transaction Controller to get the full load time of the page and nested AJAX/XHR calls.

When it comes to running the JSR223 Sampler with the Groovy scripting engine in Blazemeter’s Cloud, make sure that you provide the groovy-all.jar along with your .jmx script through the File Upload dialog. Blazemeter will pick it up and make it available to all the engines on the load test.

5cf052c8fe71698255a9fb29b0d93244.png

How to Write a Custom AJAX Request Sampler

Sometimes even scripting isn’t enough to implement a missing feature. In this section, I’ll look at  the process of creating custom JMeter Samplers, taking several URLs and their requests in parallel by several threads.

The JMeter source is available in the Apache JMeter Downloads area. Here you’ll be able to find anExampleSampler, showing you how the custom sampler should be implemented. I’m going to make it capable of sending HTTP requests and status reports by overriding theSampleResultsample (Entry e) method declared inSamplerinterface with the code used to send parallel requests with multiple thread. This overrides the parent Thread Group limitations like I did with the JSR223 Sampler - but it also adds extra reporting and exit criteria. The project structure is relatively complex so I’ll provide it as a separate source code bundle - rather than inline it into this post.

Disclaimer: the example ajax-sampler source code is provided for your reference only. It’s not a fully functional sampler and doesn’t support components like the HTTP Header Manager, HTTP Authorization Manager, etc.

To get the AJAX Sampler:

For “build from source” way: execute the mvn install command from ajax-sampler folder

Copy the blazemeter-ajax-sampler-1.0-SNAPSHOT.jar library from ajax-sampler/target folder to the /lib/ext folder of your JMeter installation

Restart JMeter

Once you’ve successfully completed it, you should see an additional “Example Sampler” with this GUI:

1ee1ea4985a68f38d8b18f79efedc03e.png

You can use this sample to set a number of send requests to specified URLs.  The sampler will execute requests to all the specified URLs asynchronously by using an equal number of threads and URLs.

Method - HTTP Method to execute (GET, POST, PUT, etc.)

URL - self-explanatory, an endpoint for the request

Value - in case of POST, PUT, etc., the request body can be specified here

Now let’s go back to the Liferay scenario, which has two portlets being loaded through AJAX calls. We’ll need to have the following Test Plan Structure:

Test Plan

Thread Group

Transaction Controller

HTTP Request - GET request to main page

POST request to Currency Converter portlet

Post request to RSS portlet

The POST request details will need to be populated with captured values through Firebug or Wireshark

c0f2748e93a34fad15a09c58671b8ef3.png

To run the test with an AJAX extension in Blazemeter’s Cloud, you’ll need to provide the following:

An AJAX.jmx test plan

The blazemeter-ajax-sampler-1.0-SNAPSHOT.jar extension library

dc99a26442336c39119449d17d933be1.png

Here’s what the load report for the Test Plan looks like:

1342f32e6fb04df3809a4b65fd530b2a.pngThis report reveals that the main request to the Liferay home page tool took 722 ms and the cumulative time of the execution of AJAX requests was 131 ms, 853 ms in total.

Take a look in the Logs section for more information on the number of URLs hit and the HTTP results received.

61cb07e4e69b73f665f805faedd763f0.png

If you disable the AJAX Extension and retry the same test, you’ll see that only the main request will be executed without any XHR-generated calls and the timings are lower.

9b7a494cf85c6b9f058ad58f16c9b0dd.pngTo summarize, you have three options when it comes to performing application testing on AJAX powered websites. Here's a table of your options and the pros and cons of each one.

Approach

Pros

Cons

WebDriver Sampler

Gives a real browser experience

Requires a lot of dependency libraries. In some cases, these dependencies clash with JMeter libraries

Requires additional Selenium specific coding to wait for all AJAX events to finish

Consumes a lot of CPU/RAM

It's recommended to limit threads to 1 only

JSR223 Sampler and groovy

Performance is very close to Java code

Requires the groovy library in the classpath

In case of inner classes all Java limitations apply

Custom Sampler

Native Java performance

Flexibility and extensibility

Full access to JMeter API

Requires Java development skills and extra time for implementation

And...that’s pretty much it on testing AJAX-enabled apps with Apache JMeter.

As always, I’d love to hear your comments and questions.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值