Testing ZK with JMeter

asked 2010-09-24 16:53:42 +0800

gvast gravatar image gvast
6 1

updated 2010-09-24 22:01:10 +0800

I'm trying to make a JMeter test for a login application. I took the login sample in ZK-Demo, that asks for a user and password and after pressing login button you get the user name within a welcome message and a logout button.

My JMeter tests run fine, until they attempt to login. At that point all I get back is a page with a redirect to: /<appname>/timeout.zul. As far as I can tell, I am passing all the required cookies and headers, but I must be missing something. I think that the problem is in ZK-SID var in header that is dynamically by (I guess) the ZK System. In particular, I would like to know if there is a way to predict the value of the ZK-SID header. Any help or other advice, about how to test ZK application (with session control) in JMeter, will be very much appreciated.

delete flag offensive retag edit

12 Replies

Sort by ยป oldest newest

answered 2010-09-26 20:38:31 +0800

PeterKuo gravatar image PeterKuo
481 2

For ZK test, most problem comes with UUID.
It's dynamic, and different every time to distinguish widget in different desktop.

You may refer to following thread first.

link publish delete flag offensive edit

answered 2010-09-27 09:24:08 +0800

gvast gravatar image gvast
6 1

updated 2010-09-27 09:38:37 +0800


I had already seen that post. But, I can make functional testing with sahi, because of I can program click an keyboard strokes without problem, even I can click on images. Also I have create fix IDs with the interface used in that posts. In JMeter you web sites sending GETs and POSTs, and that seems not to be enough!!! I need to know if some one had tested a full application with JMeter, navigating through the site. Someone could help me tell me which javascript create the ZK-SID header var. I don't know if that the right solution or JMeter is not the tool for ZK load/stress testing. Thanks anyway!

link publish delete flag offensive edit

answered 2011-11-22 10:49:43 +0800

Maurus gravatar image Maurus

I wonder if you could solve your problem and if so how you did it?

link publish delete flag offensive edit

answered 2011-12-04 11:07:25 +0800

simonmassey gravatar image simonmassey
90 1

Its has been a while but the way that I have done JMeter with ZK3.x in the past is that the the ZK-SID was actually in the page returned by the first call. Jmeter is able to use a regular expression to extract any value from a page into a variable to be used in all subsequent calls. So you add action to the GET which extracts the string value from the page into a variable called something like ZID then you go through all the AJAX POST nodes you recorded and replace the value your recorded with ${ZID} to have jmeter send the variable you captured. The jmeter test files are actually simply xml files; so you can use a text editor to do search and replace to easily modify the whole script.

Seems like a lot of people ask the same question so I might get around to creating a sample of this...


link publish delete flag offensive edit

answered 2011-12-04 17:31:43 +0800

simonmassey gravatar image simonmassey
90 1

Okay got a jmeter test working to try out a simple test of a page running on the Heroku cloud.

The sourcecode is ZKToDo2 on GitHub.

The Jmeter test is testHello.jmx which tests this simple page hello.zul.

In order for jmeter to 'find' the same components on the page I used this ID generator GrinderIdGenerator.java which is an update the version first presented here. I have commented out in zk.xml and web.xml how to enable it as per that old article.

The ZK-SID is just a counter (sequence id). So in the test script I use a "BeanShell PostProcessor" to setup a variable:

var zsidstring = vars.get("ZKSID");
if( zsidstring == null ) {
	var nowDate = new Date();
	var ts = nowDate.getTime();
	OUT.println("init ZKID="+ts);
} else {
	OUT.println("no new ZKID");

and after each zkau sample which uses it I use a postprocessor to increment it:

var zsidstring = vars.get("ZKSID");
var zsid = Long.parseLong(zsidstring);
zsid = zsid + 1;
OUT.println("ZKID "+zsidstring + " > " + zsid);

To capture the ZK-DesktopId I used a "Regular Expression Extractor". That sets ZKDID from the headers sent on the first page.

Then throughout the script the POST samples use dtid=${ZKDID} and the header managers use ZK-SID=${ZKSID}.


link publish delete flag offensive edit

answered 2011-12-05 16:55:07 +0800

simonmassey gravatar image simonmassey
90 1

updated 2011-12-05 16:57:01 +0800

Oh one load testing "gotcha"; you need to put in the "rmDesktop" ajax event to simulate the user closing the window if you don't have an explicit logout button to record clicking.

So with the demo code above if you set the cookie manager clear the session cookie each loop then it will simulate a new user/browser every loop. These will get a new zkdesktop every time it loops. The old zkdesktops from the previous iterations will still be in memory on the server. Over time that will be a drain on resources and will crash the app. Yet most real users will logout, close the window/tab or move to a new webpage/site. The window.onunload event for your zk page will send an ajax message to remove the zk desktop from the server. Only a few users will ever crash their browser or loose their network connection such that their desktops dont get removed and have to timeout.

So to simulate reality you need to record the ajax rmDesktop event and ensure that you send that to simulate a user closing the window when they are "finished" with the site. What you really want to do is use the jmeter recording proxy to record a real user using you app. Then set the jmeter timers to be random and when played back on a single loop to appear just like the real user behavior. Then figure out how many loops to do for the "duration of time that a single user will work with the website". Only after that many loops clear the cookie after sending the rmDesktop event (user closes browser tab event). Only through careful tuning of the test will you get one which reflects reality and will show you how many real users your website can truly be expected to handle.

In fact writing a "bad test" which crashes a webapp is all too easy. For example how long does a use think between mouse clicks? Longer than you might think. And do all threads start at the same time and click buttons the same spacing apart? (that is clearly more stressful than many users working independently with random timings). So make sure you put in randomized timers to ensure that the server sees traffic like a bunch of people working independent.


link publish delete flag offensive edit

answered 2011-12-05 23:45:03 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16

Hi Simon,

time for writing a smalltalk about JMeter a zk application ?

In fact i'm interesting how does other developers find out how many user can work simultanousily on a zk app on one standard server ( 4 GB / 1 x 2,6 GHZ ) or ( 6 GB 16 x 2,6 GHZ virtual machine )


link publish delete flag offensive edit

answered 2011-12-06 17:37:34 +0800

sousa1981 gravatar image sousa1981
573 4

updated 2011-12-06 17:38:02 +0800


link publish delete flag offensive edit

answered 2011-12-06 19:55:13 +0800

sousa1981 gravatar image sousa1981
573 4


Can you post your jmeter.out result please?

To simplify watch if the server is receiving the request properly and response it, I made simple modifications to hello.zul to log an afterComposer and Click Event.
I found that, only afterComposer is being logged, but JMeter show like everything is OK.

My hello.zul is

<?xml version="1.0" encoding="UTF-8"?>
<?page title="Hello"?>
<window title="My First window at Heroku" border="normal" width="200px" apply="com.xpto.zkjmeter.HelloController">
	<button id="btnHi" label="Hi" />

So the com.xpto.zkjmeter.HelloController is simple:

package com.xpto.zkjmeter;

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericForwardComposer;

public class HelloController extends GenericForwardComposer {

	private static final long serialVersionUID = 1L;

	protected final Log LOG = LogFactory.getLog(this.getClass());

	private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS");

	public HelloController() {

	public void doAfterCompose(Component component) throws Exception {

		String message = MessageFormat.format("Entrou no Controller ''{0}''", DATE_FORMAT.format(Calendar.getInstance().getTime()));

	public void onClick$btnHi(Event event) {
		try {
			String message = MessageFormat.format("Button btnHi Data ''{0}''", DATE_FORMAT.format(Calendar.getInstance().getTime()));


			String helloName = Executions.getCurrent().getParameter("helloName");
			if (helloName == null || helloName.trim().equals("")) {
				helloName = "Marcos de Sousa";

			LOG.info("helloName: " + helloName);
		} catch (Throwable e) {
			LOG.error("no name give. ", e);



link publish delete flag offensive edit

answered 2011-12-07 13:05:50 +0800

sousa1981 gravatar image sousa1981
573 4

I resolved the issue. I was using wrong id for button while executing request

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools




Asked: 2010-09-24 16:53:42 +0800

Seen: 2,046 times

Last updated: Dec 15 '11

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More