Monday, June 09, 2008

Software Tests in GWT

Since software development in GWT is based on Java, many conventional and well-practiced test techniques related to Java can be utilised for applications developed using GWT. Following test techniques are supported by GWT:

· Unit testing (JUnit by extending GWTTestCase)
· Performance testing (Benchmarking, by extending Benchmark)
· Robot testing ( Selenium, UI test)
· Continuous Testing (Cruise Control)

Unit Test (JUnit)


Out-of-box JUnit unit test support is shipped with GWT for client and server side synchronous and asynchronous testing. Test cases that wish to make use of unit tests extend GWTTestCase. By default, tests are run in hosted mode with an invisible GWT browser. GWT JUnit tests are generally designed for non-UI testing. More precisely they are used to test the logic and functionality of GWT applications (especially server side functionality). For UI triggered robot tests Selenium should be preferred.

Since GWT unit tests extends standard JUnit (version 3, not JUnit4), conventional JUnit test approaches (such as use of Assert assertion methods) can be used for GWT unit test cases. Each GWT JUnit test extends GWTTestCase and implements getModuleName() method which defines the interest of GWT module.

GWT JUnit supports asynchronous tests by introducing two methods, finishTest and delayTestFinish. delayTestFinish makes sure that test does not terminates immediately but wait for a period of time to handle asynchronous callbacks. As soon as a result obtained from asynchronous callback, finishTest should be invoked to finish test successfully, otherwise delayTestFinish will cause a timeout exception to fail test. In addition those, chain pattern can be implemented for invoking several asynchronous serially to simulate UI cases.

JUnit tests can be run either in hosted (default) or web mode (-Dgwt.args="-web" ,with various browsers). During hosted mode, cross browser compatibility is not checked. For this purpose, tests must be run against different browser in web mode. Corresponding to application size, compilation time can be longer (1-5 min) in hosted compared to web mode.

Please note that, in GWT 1.5 MS2 and RC1, the base test class which implements getModuleName() method must have the same package name as the package name of the module entry class. For example, for module com.booo.Boo.gwt.xml, the package name of the base test class should be com.booo.client

Performance (benchmarking)

With GWT 1.4, a benchmarking scheme is introduced to test performance of client side code. For profiling and reporting, in GWT, a benchmarking test class must extend Benchmark which is subclass of GWTTestCase. In addition to standard JUnit facilities, Benchmark provides automatic iterative test case invoking for given range or Iterator. Please refer to [1] and [2] for further information.

The biggest disadvantage of Benchmarking in GWT, unfortunately, it does not yet support asynchronous calls and access to server side code. This severely limits its use for testing performance of a whole application. Instead, it is better used to benchmark stand alone client side code.

Robot (Selenium)

Selenium is a de facto standard for robot UI testing. Selenium performs automatic UI trigger based tests against a given valid URL. Selenium utilises generally HTML elements' ids to carry out operations such as clicking buttons, editing input text or selecting an item from a list box.
These operations can be performed manually by a user on Firefox with the Selenium IDE which records all of these operations sequentially and then converts them to a Selenium JUnit class (extending SeleneseTestCase). These test cases can be aggregated in continuous tests similar to standard JUnit tests. Selenium supports continuous tests out-of-box with selenese Ant tasks [3].

Since any changes on the UI directly affect these tests, UI developers have to be careful in terms of naming or identifying HTML elements. If Selenium testing is chosen for robot UI testing a systematic schema has to be agreed and developed between QA and the UI developer. In addition to that, UI developer must use appropriate UI widgets and libraries which support identifying HTML elements for Selenium test.


GWT and continuous testing (CC)

Since GWT takes full advAntage of Java, it is possible to use a continuous testing schema for above tests. For example, Google uses GWT with CruiseControl for continuous testing. Eric Ayers from Google has described how they use CC and GWT in this link:

http://groups.google.com/group/Google-Web-Toolkit/msg/006793285e736d23

But for future reference, I am quoting it here again:

“…
The best advice I can give you for setting up a project build is to look at one of the projects on code.google.com:

  • - gwt-google-apis
  • - gwt-api-interop
  • - google-web-toolkit-incubator

All of these are projects that use GWT as a library and we build from cruisecontrol at the top level and 'ant' build files to actual compile everything. The ant build files are included in the subversion repository, but the Cruise \control files are not. For Cruisecontrol, setup your project as follows:


Create a directory with the download of GWT you want to build against. This directory you need to set as the ant property 'gwt.home' You may also need a directory with the 'tools' directory from the GWT subversion respository (but I'm not certain you need this). This directory you need to set as the ant property 'gwt.tools'

Now, look at the common.ant.xml file in one of the projects I mentioned. It has rules for building and testing GWT projects. You will probably need a copy of the direcory 'build-tools' in order to use all of the rules. You can copy this from the GWT repository or use an Subversion 'external' refernece to pull it in if your project uses subversion.

Our cruise control configuration file does the following:

  • - Refreshes the project code from SVN,
  • - Pulls the latest version of the GWT ''tools' directory
  • - builds the ant targets 'build' and 'test'
  • - runs an artifactspublisher to pull down the 'dist' directory as well as the unit test reports.

...“

I have followed his instruction and managed create an ant script for CC. As he mentioned above, even though, these sample build files based on GWT_tools, you can create simpler build files by ignoring tools.


Conclusion

Since development in GWT is based on Java, many testing techniques common to the Java domain can be applied to GWT. GWT supports many standard testing techniques such as unit testing (JUnit), performance (Benchmark) and UI triggered robot tests (Selenium).


Generally, it is recommended to use GWT JUnit for non-UI based test such as logic and functionality test which may or may not require client and server asynchronous communication.

At the time of writing this report, GWT Benchmark does not support asynchronous call and access to server side code, therefore benchmarking in GWT is not useful for performance tests of complete application but only for isolated client side logic and functionality.

For UI trigged testing, Selenium can be used but since Selenium tests are tightly-coupled to HTML elements a systematic agreement has to be developed between UI and test developers against UI code changes and type of widget will be used.

All of these tests can be aggregated in Cruise Control for continuous testing.

For detailed information regarding benchmarking and JUnit tests in GWT, please refer [2].

References

  1. “Google Web Toolkit Applications” by Ryan Dewsbury. Page (170-180) for JUnit and benchmarking.

No comments: