One of the nice aspects of Google’s Web Tool kit is its built-in developer testing functionality à la JUnit. Not only does GWT give you the ability to develop Ajax components within Java (as opposed to JavaScript) but by standardizing the development platform on Java, they’ve facilitated the use of testing Ajax related code with what’s arguably the standard testing platform for Java developers. One key thing to keep in mind, however, is that Google’s GWTTestCase isn’t meant to test UI related code– it’s meant to facilitate testing asynchronous aspects that can be triggered by UI interactions.

service-01

For example, the image to the right demonstrates an Ajax application that retrieves definitions for a given word. It is a rather simple problem domain– once a word is entered into the web from and a user presses the submit button, an asynchronous call is made to retrieve the word’s definition from a server side database.

Once the definition is retrieved from the database, it is inserted below the form as follows:

service-02

Because the brunt of the work related to this simple web flow is essentially the heart of Ajax, the meat of the code is executed when the submit button is clicked. Consequently, one must approach writing this particular code in such a manner so as to facilitate testing it programmatically via JUnit. Sure, you could indirectly test the code via functionally executing the flow either manually or in an automated fashion with Selenium, but by using JUnit, you can essentially test the server side communication work more easily.

For example, the submit button is configured with a ClickListener that essentially defers logic to a UI specific method.

btn.addClickListener(new ClickListener() {
 public void onClick(Widget sender) {
  submitWord();
 }
});

The submitWord method is UI specific because it uses UI components.

protected void submitWord() {
 String word = this.getTextBox().getText().trim();
 this.getTextBox().setEnabled(false);
 this.getDefinition(word);
}

Note how the submitWord method then calls the getDefinition method, which takes a String. This method tries not to be UI specific (as much as possible) and accordingly can be tested effectively with JUnit.

protected void getDefinition(String word) {
 final Label output = this.getOutputLabel();
 WordServiceAsync instance = WordService.Util.getInstance();
 instance.getDefinition(word, new AsyncCallback() {
   public void onFailure(Throwable error) {
    Window.alert("Error occured:" + error.toString());
   }
   public void onSuccess(Object retValue) {
    output.setText(retValue.toString());
   }
  });
 this.getTextBox().setEnabled(true);
}

Note, this method creates an anonymous class of type AsyncCallback, which limits how much you can do inside of it; hence, the definition is actually set as a Label’s text. This means that in order to validate things work, one must grab an instance of the Label and assert that its text is the correct definition.

Finally, because this code is essentially Ajax, which has an ‘A’ for asynchronous, you must force JUnit to wait using a Timer object, which is provided in the GWT.

public void testDefinitionValue() throws Exception {
 final WordModule module = new WordModule();
 module.getDefinition("pugnacious");
 Timer timer = new Timer() {
   public void run() {
    String value = module.getOutputLabel().getText();
    assertEquals("should be...", "...", value);
    finishTest();
   }
 };
 timer.schedule(200);
 delayTestFinish(500);
}

Note the call within the Timer to obtain the definition from the Label (getOutputLabel().getText()).

As you can see, GWT facilitates testing of server side interaction code quite nicely– that’s a huge feature if you plan on building Ajax enabled web applications. Plus, UI related code can (and should) be tested by Selenium as this is what Selenium was designed for.