How to Test ZK Application with Selenium

From Documentation
Revision as of 01:17, 7 March 2011 by Jimmyshiau (talk | contribs) (→‎How to ?)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
DocumentationSmall Talks2009FebruaryHow to Test ZK Application with Selenium
How to Test ZK Application with Selenium

Author
Ryan Wu, Engineer, Potix Corporation
Date
February 13, 2009
Version
In ZK 3.0 (or later)

Introduction

About this article

First, thanks for the contribution of ZK Unit Testing by Luca Vix Visconti. He introduced how to test ZK application with Selenium Test Framework[1].
And in this article, I modify the ZK TODO [2] and i will show you how to test it with Selenium by using a ZK id generator.

Note: With the current version ZK 5.0.3 the manual implementation of the ID generator is no longer required.


Environment

ZK TODO List

Following are the prerequisites of this test.

  • Selenium Selenium-RC-1.0-beta-2
  • ZK 3.5.2
  • JUnit 4.5 [1]
  • Firefox 3.0.6 [2]
    • Add-on : Firebug 1.3.2 [3]
  • Eclipse 3.4 [4]
  • The application you wanna test
    ZK TODO
    A simple application which can add/remove/update something about what you want to finish.

Steps

Initialize your testing environment

Follow the steps in ZK Unit Testing,

  1. Setting up the Selenium Remote Control
  2. Configuring Firefox

Then check if you can connect to you ZK application correctly.

Create id generator for your ZK application(s)

Now we have to write test case for ZK TODO, before that , let's take a look of the generated HTML by using Firefox with Firebug.

Why ?

ZKTODO2.PNG
I "Inspect" the input element of first textbox, i want to get it's ID.
First time i get z_8j_h, but second time i get z_aj_h .

ZKTODO3.PNG ZKTODO4.PNG

Although Selenium have good mechanism of locator, but it is more convenient if we know the ID of it. (If your case is complicated, you will get a long, hard to find XPath)
So we can use the id generator function of ZK to generate predictable id of HTML element. Thus, we can get it by using Selenium.method("the name").

How to ?

To make id of ZK components predictable, you have to create a Id Generator. The following example is a class name DemoIdGenerator, which implements IdGenerator Class.

public interface IdGenerator {
	public String nextComponentUuid(Desktop desktop, Component comp);
	public String nextPageUuid(Page page);
	public String nextDesktopId(Desktop desktop);
}

These three method have similar purpose : return the ID of Component, Page, and Desktop. If return null , it will generated the default ID.

public class DemoIdGenerator implements IdGenerator {
	public String nextComponentUuid(Desktop desktop, Component comp) {
		int i = Integer.parseInt(desktop.getAttribute("Id_Num").toString());
		i++;// Start from 1
		desktop.setAttribute("Id_Num", String.valueOf(i));
		return "zk-comp-" + i;
	}

	public String nextDesktopId(Desktop desktop) {
		if (desktop.getAttribute("Id_Num") == null) {
			String number = "0";
			desktop.setAttribute("Id_Num", number);
		}
		return null;
	}

	public String nextPageUuid(Page page) {
		return null;
	}

}

Note: For ZK5 you need to change the line 'return zk-comp-" + i; to return "zk_comp_" + i; (see http://sourceforge.net/tracker/?func=detail&aid=2969059&group_id=152762&atid=785191)

In DemoIdGenerator, i set an attribute "Id_Num" to the desktop, it will plus one when each component is created.
And it will generate the component's uuid with "zk-comp-" prefix , but there are some special case we need to notice:

  1. Two or more people connect to same zul page
    Because they have different desktop, so the same component (created in same sequence) will got same id.
  2. A zul page included by another zul page
    The desktop is the same, so the components in the inner page will continue the counting of Id_Num and get new ID.

After creating the DemoIdGenerator, simply add it into your zk.xml and restart the tomcat.

	<system-config>
		<id-generator-class>zk.impl.DemoIdGenerator</id-generator-class>
	</system-config>

Then the id of components in you application will change.

ZKTODO5.PNG

Start to test

We assume your already configured you testing environment and download the project file from here.

  1. Add the project into your workspace (it will be a dynamic web project named "SeleniumHowTo")
  2. Open you Selenium-server in default port (4444)
  3. Run the zk.test.DemoTest.java
    It will do things following :
    1. open link http://localhost:8080/SeleniumHowTo/todo.zul
    2. Enter "Somthing important", "1", and "Feb 14, 2009" into the three textbox
    3. Press the ADD button
    4. Enter "Somthing nothing", "3", and "Feb 15, 2009" into the three textbox
    5. Press the ADD button
    6. Check if the list item have correct information.
    Here are the test code :
package zk.test;

import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.SeleneseTestCase;
import com.thoughtworks.selenium.Selenium;

public class DemoTest extends SeleneseTestCase {
	private Selenium browser;
	public void setUp() {
		browser = new DefaultSelenium("localhost", 4444, "*firefox", "http://localhost:8080/");
		browser.start();
	}
	public void testTodo() {
		try {
			Thread.sleep(5000);
			browser.open("http://localhost:8080/SeleniumHowTo/todo.zul");
			System.out.println("Enter first thing");
			browser.focus("zk-comp-13");
			browser.type("zk-comp-13", "Somthing important");
			Thread.sleep(1000);
			browser.focus("zk-comp-15");
			browser.type("zk-comp-15", "1");
			Thread.sleep(1000);
			browser.focus("zk-comp-17!real");
			browser.type("zk-comp-17!real", "Feb 14, 2009");
			Thread.sleep(1000);
			browser.focus("zk-comp-18!real");
			browser.click("zk-comp-18!real");
			Thread.sleep(1000);
			System.out.println("Enter second thing");
			browser.focus("zk-comp-13");
			browser.type("zk-comp-13", "Somthing nothing");
			Thread.sleep(1000);
			browser.focus("zk-comp-15");
			browser.type("zk-comp-15", "3");
			Thread.sleep(1000);
			browser.focus("zk-comp-17!real");
			browser.type("zk-comp-17!real", "Feb 15, 2009");
			Thread.sleep(1000);
			browser.focus("zk-comp-18!real");
			browser.click("zk-comp-18!real");

			Thread.sleep(1500);

			assertEquals("Somthing important", browser.getText("zk-comp-22!cave").trim());
			assertEquals("1", browser.getText("zk-comp-23!cave").trim());
			assertEquals("2009-02-14", browser.getText("zk-comp-24!cave")
					.trim());

			if (!browser.getText("zk-comp-26!cave").trim().equals("Somthing nothing")
					|| !browser.getText("zk-comp-27!cave").trim().equals("3")
					|| !browser.getText("zk-comp-28!cave").trim().equals("2009-02-15"))
				fail("Update error!");
			browser.close();
			System.out.print("done!");

			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void tearDown() {
		browser.stop();
	}
}

The items you have to test is depends on the purpose and function of you application.
If you have problems about how to create a good test code, you can take a look the documentation of Selenium for more information.

Result

Appendix

Download




Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.