The Dawn of ZK Application Test Suite:Mimic Library"

From Documentation
Line 17: Line 17:
 
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.
 
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.
  
<!-- image of library concept -->
+
[[File:Smalltalk-MimicLibraryConcept.png]]
  
 
== Limitation==
 
== Limitation==

Revision as of 06:20, 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. That means testers have to deploy the web application to a server before performing a unit test. But to run 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.

Introduction to 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.

Smalltalk-MimicLibraryConcept.png

Limitation

  • 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.

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: 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.