On Web Load Testing

JavaScript in load testing

Sometimes people ask if a web load testing tool supports JavaScript. They basically want to know if it is possible to apply the tool to test a web application implemented with JavaScript. The answer is usually obvious. Most load testing tools do not need to execute JavaScript code contained on web pages. This code is executed by the browser when the test is recorded.

So, the only requirement for the load testing tool is that it should be able to record all AJAX requests produces by the JavaScript code on the loaded page. These requests are used to update the page content in the browser. Since they carry additional data, they should be reproduced during the test when the user session is replayed.

At the same time scripting languages play very important role in load testing. Some tools can pre-compile entire test into a script, so that it can be executed as a stand-along task. The ability to modify these scripts provides the most flexible way to create custom test scenarios. However such approach requires significant programming background for the test engineers. That is why it is usually preferable to remain on a higher level and treat each test profile as a sequence of HTTP requests.

To simulate a new user session correctly it is not sufficient to replay the recorded session as is. To handle dynamic content of your web site you need to parameterize the initially recorded requests. This may be required for two reasons.

So, you need to have a way to insert dynamic values into HTTP requests. You can either extract these values from server responses, or read them from external sources (files or databases).
Each load testing tool has a number of functions that can accomplish these tasks. Usually these functions cover most common cases; however practice shows that to handle all possible situations we need to have some more general solution.

That is where we are back to JavaScript. In fact, most load testing solutions use scripting languages as a supplementary tool. The goal is to combine the flexibility with ease of use. That is why on one hand we might want to keep representing each virtual user profile as a sequence of requests (as opposed to creating a script that produces the whole user session). On the other hand we want to let test designers insert JavaScript functions between any two requests to handle complex cases.

Let’s see how this is done in WAPT. When you open a profile in the left view, a JavaScript operator looks like an additional node in the list of requests. You can insert as many such nodes as you need.

If you select the operator, you will see that it contains JavaScript code inside it. It will be displayed in the right view. Initially it is empty and only includes a comment with a short instruction.

The most important thing is that from this code you can access the latest server response and all internal variables. The latter means that you can read and modify the values of these variables. So, you can use the script both to process the result of the previous request and to prepare values of parameters for the next one.

For example, imagine that we need to test a search feature of a web application. We have a list of 100 keywords and want each session to use from 1 to 10 randomly selected keywords for a search string. It is not possible to implement such complex task with help of regular WAPT functions, because they can only read values from a file one by one, where as we need to construct a new string from a set of randomly selected values. Fortunately JavaScript has a rich set of string functions, so it is very easy to implement the above test in that scripting language.

For the same reason JavaScript is very convenient for processing server responses in order to extract values from them. The most common way to do this is to use regular expressions (RegExp). You can also implement advanced logics when you need to select from several found values, or exclude unneeded ones.

In WAPT JavaScript code can also write messages and errors to the test execution log. This can be used to debug tests, because you can output intermediate session data. However it is even more important that you can use this to validate server responses. Again, in simple cases WAPT can perform response validation by searching a specified keyword inside the response. However this is not always sufficient and it may appear that more complex criteria have to be applied.

Conclusion: JavaScript is a powerful and flexible tool that can be used in load and performance testing for 3 different purposes.

  1. Calculation of values for the parameters of requests inside user sessions.
  2. Extraction of values from server responses.
  3. Validation of server responses.

Just a final note: each great thing has a small flaw. In case of JavaScript it is the efficiency. The execution of JavaScript code takes much more system resources than the use of the native functions of a load testing tool. You should take this into account when designing your tests and planning hardware configuration for running them.