The Dawn of ZK Application Test Suite:Mimic Library"

From Documentation
Line 9: Line 9:
 
= Opening =
 
= Opening =
 
<!-- agile => test driven => unit-test -->
 
<!-- agile => test driven => unit-test -->
In agile software development, developers modify their codes frequently for requirement change or refactoring, so they also perform unit test frequently to ensure the software quality. In ZK-based application, the composer which is tightly-couple with ZUL is hard to be unit tested because it is instantiated when a ZUL is requested by a browser. Testers may deploy the web application to a server and test it with the browser. But writing automation test to control a browser is an issue, and testing for different browsers is also a trouble. Not to mention that running a unit test in an application server is time-consuming and could be agile developer's darkest time. Don't be depressed, let me light your path with twilight of ZK Test Suite - '''Mimic Library'''.
+
In agile software development, developers modify their codes frequently for requirement change or refactoring, so they also perform unit test frequently to ensure the software quality. In ZK-based application, the composer which is tightly-couple with ZUL is hard to be unit tested because it is instantiated when a ZUL is requested by a browser. Hence '''TDD''' (Test-Driven Development) cannot work under this situation. Agile developer may deploy the web application to a server and test it with the browser. But writing automation test to control a browser is an issue, and testing for different browsers is also a trouble. Not to mention that running a unit test in an application server is time-consuming and could be agile developer's darkest time. Don't be depressed, let me light your path with twilight of ZK Test Suite - '''Mimic Library'''.
  
 
= Mimic Library : No Server Test =  
 
= Mimic Library : No Server Test =  

Revision as of 09:18, 23 March 2012

WarningTriangle-32x32.png This page is under construction, so we cannot guarantee the accuracy of the content!


DocumentationSmall Talks2012AprilThe Dawn of ZK Application Test Suite:Mimic Library
The Dawn of ZK Application Test Suite:Mimic Library

Author
Hawk Chen, Engineer, Potix Corporation
Date
Version
0.9.0 Freshly

Opening

In agile software development, developers modify their codes frequently for requirement change or refactoring, so they also perform unit test frequently to ensure the software quality. In ZK-based application, the composer which is tightly-couple with ZUL is hard to be unit tested because it is instantiated when a ZUL is requested by a browser. Hence TDD (Test-Driven Development) cannot work under this situation. Agile developer may deploy the web application to a server and test it with the browser. But writing automation test to control a browser is an issue, and testing for different browsers is also a trouble. Not to mention that running a unit test in an application server is time-consuming and could be agile developer's darkest time. Don't be depressed, let me light your path with twilight of ZK Test Suite - Mimic Library.

Mimic Library : No Server Test

Mimic library enables tester to test their composer without application server, of course without browser, either. Through this library, tester can mimic user interactions to applications such as clicking or typing to verify composer's (controller layer) data and logic. All they have to do is to write a regular unit test case with JUnit and use mimic library's utility class to interact components on ZUL. Then run the test case, it will load your project's ZUL with a server emulator. But no screen is rendered, it just simulates user interaction to the server. Tester can verify result by checking component's property or model.

No deploying to server, no rendering on browser, the unit test case can be executed in very short time. This is very helpful to frequently unit testing during agile development process.

The concept is as follows:

Smalltalk-MimicLibraryConcept.png

Tester writes test case to manipulate mimic component with mimic operation which simulates user action like clicking or typing. These operations will be sent to server emulator and related event handlers written in a composer will be invoked to change component's status. Tester can check component's properties to verify the result of user action. It might be a label's value changes or a listbox increases one item. Those behaviors that reflect on component's properties can be verified.

Limitation

As this library focuses on testing composer's logic on the server side, there are some limitation you should know:

  • Functions that depend on the application server cannot work.
    Test cases are run in simulated environment, all functions that requires an application server cannot work properly. (i.e. JNDI, or JTA) If users’ AUT project adopts such container-provided services, they need extra work to make it work normally out of a container, i.e. use Test Double like fake object.
  • Cannot test client’s behavior.
    In ZK-based application, some behaviors are handled by browser(JavaScript), e.g. popup menu. As server side is not aware of these behaviors, we cannot verify it from server side.
  • Cannot test some visual effects.
    It cannot verify any behavior that doesn't reflect on component's properties like animations, or a component's visual effect.

Test a CRUD example application

To demonstrate how to test an application with mimic library, we create a simple todo list application. It allows us to add, update, delete, and view todo items. Each item has 3 fields: item name, priority, and date.

File:Smalltalk-zats-todolist.png

todo.zul

	<listbox id="listbox" rows="4"  model="@{win$composer.allTasks, load-after='add.onClick, update.onClick, delete.onClick'}" >
	<!-- other components -->
	</lisbot>
	<!-- other components -->
			Item:
			<textbox id="itemBox" 
			value="@{win$composer.selected.name, load-after='listbox.onSelect, add.onClick, update.onClick, delete.onClick, reset.onClick'}" cols="25" />
			Priority:
			<intbox id="priorityBox" 
			value="@{win$composer.selected.priority, load-after='listbox.onSelect, add.onClick, update.onClick, delete.onClick, reset.onClick'}" cols="1" />
			Date:
			<datebox id="dateBox" format="yyyy-MM-dd"
			value="@{win$composer.selected.date, load-after='listbox.onSelect, add.onClick, update.onClick, delete.onClick, reset.onClick'}" cols="8" />
	<!-- other components -->

Setup

Before writing test cases with mimic library, you have to include zats-mimic.jar and jetty.jar to your project.

Write a Test Case

The steps to write test case are:

  1. Setup web application content path
  2. Start a conversation with a ZUL
  3. Find a component
  4. Perform an action on a component
  5. Verify result by checking a component’s state
  6. Tear down

The test case is to verify composer's logic. In our example application, there are 4 main function: Add, Update, Delete, Reset, the test case verify them one by one.

package org.zkoss.zats.example.testcase;

import static org.junit.Assert.assertEquals;
import static org.zkoss.zats.mimic.Searcher.find;
//remove other import for brevity

public class TodoTest {
	@BeforeClass
	public static void init() {
		Conversations.start("./src/main/webapp"); 
	}

	@AfterClass
	public static void end() {
		Conversations.stop();
	}

	@After
	public void after() {
		Conversations.clean();
	}

	@Test
	public void test() {
		//visit the target page
		Conversations.open("/todo.zul");

		//find components
		ComponentAgent itemName = find("textbox");
		ComponentAgent priority = find("intbox");
		ComponentAgent date = find("datebox");

		//add
		itemName.as(TypeAgent.class).type("one-item");
		priority.as(TypeAgent.class).type("3");
		date.as(TypeAgent.class).type("2012-03-16");
		find("button[label='Add'] ").as(ClickAgent.class).click();
		
		//verify each listcell's label
		ComponentAgent listbox = find("listbox");
		List cells = listbox.getChild(1).as(Listitem.class).getChildren();
		assertEquals("one-item",((Listcell)cells.get(0)).getLabel());
		assertEquals("3",((Listcell)cells.get(1)).getLabel());
		assertEquals("2012/03/16",((Listcell)cells.get(2)).getLabel());
		
		
		//update
		listbox.as(SelectAgent.class).select(0);
		//verify select
		assertEquals("one-item",itemName.as(Textbox.class).getValue());
		assertEquals((Integer)3,priority.as(Intbox.class).getValue());
		assertEquals("2012-03-16",date.as(Datebox.class).getRawText());
		//modify the todo item
		itemName.as(TypeAgent.class).type("one-item modified");
		priority.as(TypeAgent.class).type("5");
		find("button[label='Update'] ").as(ClickAgent.class).click();
		assertEquals("one-item modified",((Listcell)cells.get(0)).getLabel());
		assertEquals("5",((Listcell)cells.get(1)).getLabel());
		
		//reset
		listbox.as(SelectAgent.class).select(0);
		assertEquals("one-item modified",((Listcell)cells.get(0)).getLabel());
		find("button[label='Reset'] ").as(ClickAgent.class).click();
		assertEquals("",itemName.as(Textbox.class).getValue());
		assertEquals((Integer)0,priority.as(Intbox.class).getValue());
		assertEquals(true, date.as(Datebox.class).getValue()==null);

		//delete
		assertEquals(2,listbox.getChildren().size());
		listbox.as(SelectAgent.class).select(0);
		find("button[label='Delete'] ").as(ClickAgent.class).click();
		assertEquals(1,listbox.getChildren().size());
		
		//The following line causes IllegalStateException: Components can be accessed only in event listeners
		//find("textbox").as(Textbox.class).setValue("abc"); 
	}

Download

Comments



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