My favorites | English | Sign in

More personalization in Google Friend Connect New!

Google Web Toolkit

Unit Testing GWT Applications with JUnit

At this point, you've created the initial implementation of the StockWatcher application and it seems pretty stable.

As the code base evolves, how can you ensure that you don't break existing functionality? The solution is unit testing. Creating a battery of good unit test cases is an important part of ensuring the quality of your application over its lifecycle.

To aid you with your testing efforts, GWT provides integration with the open-source JUnit testing framework. You'll be able to create units test that you can run in both hosted mode and web mode.

In this section, you'll add a JUnit unit test to the StockWatcher project.

  1. Create a JUnit test class for StockWatcher and the scripts to run it either in hosted mode or web mode.
  2. Run the unit test.
  3. Write a unit test.
  4. Resolve a problem identified by the unit test.

Before you begin

The StockWatcher project

This tutorial builds on the GWT concepts and the StockWatcher application created in the Getting Started tutorial. If you have not completed the Getting Started tutorial and are familiar with basic GWT concepts, you can import the StockWatcher project as coded to this point.

  1. Download the StockWatcher project.
  2. Unzip the file.
  3. Import the project into Eclipse
    1. From the File menu, select the Import... menu option.
    2. Select the import source General > Existing Projects into Workspace. Click the Next button.
    3. For the root directory, browse to and select the StockWatcher directory (from the unzipped file). Click the Finish button.

If you are using ant, edit the gwt.sdk property in StockWatcher/build.xml to point to where you unzipped GWT.

JUnit 3

In order to run this tutorial, you will need to have JUnit 3 installed on your system. If you are using Eclipse, check your Eclipse plugins.

1. Creating a JUnit test

GWT junitCreator is a command-line tool that creates the files you need to begin developing JUnit tests. It generates a starter test class, scripts to run the tests from the command line, and optionally, launch configuration files for Eclipse.

For the StockWatcher project, you will run junitCreator the following parameters.

Parameter Definition Example
-junit The fully-qualified path name to junit.jar on your system.
  • (PC) C:\eclipse\plugins\org.junit_3.8.2.v200706111738\junit.jar
  • (Mac) /Users/myname/eclipse/plugins/org.junit_3.8.2.v200706111738/junit.jar
-module The GWT module for the StockWatcher application. com.google.gwt.sample.stockwatcher.StockWatcher
-eclipse The name of the Eclipse project. StockWatcher
classname The name of the test class you want to create. com.google.gwt.sample.stockwatcher.client.StockWatcherTest

To see the complete list of options for junitCreator, see the Developer's Guide, Command-line Tools > junitCreator.

  1. Open a command shell.
  2. Browse to the StockWatcher directory.
  3. At the command line, run junitCreator.
    Enter the command below on a single line. (The example is shown on multiple lines only to improve readability.)
    Replace the junit.jar path name (highlighted in the example below) with the fully-qualified path name of junit.jar on your system.
    junitCreator -junit "C:\eclipse\plugins\org.junit_3.8.2.v200706111738\junit.jar"
                 -module com.google.gwt.sample.stockwatcher.StockWatcher
                 -eclipse StockWatcher
                 com.google.gwt.sample.stockwatcher.client.StockWatcherTest
    Note: If you have not already included the GWT command-line tools in your $PATH, you will have to prefix the command with its fully-qualified path name.
  4. GWT junitCreator creates a test directory, a starter test class for StockWatcher, scripts for running test from the command line in either hosted mode or web mode, and Eclipse launch configuration files.
    Created directory test
    Created directory test/com/google/gwt/sample/stockwatcher/client
    Created file test/com/google/gwt/sample/stockwatcher/client/StockWatcherTest.java
    Created file StockWatcherTest-hosted.launch
    Created file StockWatcherTest-web.launch
    Created file StockWatcherTest-hosted
    Created file StockWatcherTest-web
    
  5. In Eclipse, refresh the StockWatcher project.
    The newly-added test files are displayed in the Package Explorer pane.
    screenshot: JUnit tests in Package Explorer

Examining the test class: StockWatcherTest.java

Take a look inside StockWatcherTest.java. This test class was generated in the com.google.gwt.sample.stockwatcher.client package under the StockWatcher/test directory. This is where you will write the unit tests for StockWatcher. Currently it contains a single, simple test: the method testSimple.

  1. Open the StockWatcherTest.java file.
    package com.google.gwt.sample.stockwatcher.client;
    
    import com.google.gwt.junit.client.GWTTestCase;
    
    /**
     * GWT JUnit tests must extend GWTTestCase.
     */
    public class StockWatcherTest extends GWTTestCase {                       [1]
    
      /**
       * Must refer to a valid module that sources this class.
       */
      public String getModuleName() {                                         [2]
        return "com.google.gwt.sample.stockwatcher.StockWatcher";
      }
    
      /**
       * Add as many tests as you like.
       */
      public void testSimple() {                                              [3]
        assertTrue(true);
      }
    
    }

Notes

[1] Like all GWT JUnit test cases, the StockWatcherTest class extends the GWTTestCase class in the com.google.gwt.junit.client package.

[2] The StockWatcherTest class has an abstract method (getModuleName) that must return the name of the GWT module. For StockWatcher, that is com.google.gwt.sample.stockwatcher.StockWatcher.

[3] The StockWatcherTest class is generated with one sample test case—a tautological test, testSimple. This testSimple method uses one of the many assert* functions that it inherits from the JUnit Assert class, which is an ancestor of GWTTestCase. The assertTrue(boolean) function asserts that the boolean argument passed in evaluates to true. If not, the testSimple test will fail when run in JUnit.

2. Running unit tests

Before you start writing your own unit tests for StockWatcher, make sure the components of the test environment are in place. You can do that by running StockWatcherTest.java which will execute the starter test, testSimple.

You can run JUnit tests three ways:

  • from the command line—using the scripts generated by junitCreator
  • in Eclipse—using the Eclipse launch configuration files generated by junitCreator
  • in manual test mode

From the command line

GWT junitCreator generated two scripts: one for testing the one for testing StockWatcher in hosted mode (StockWatcherTest-hosted) and the other for testing StockWatcher in web mode (StockWatcherTest-web). If you look inside either of these scripts, you'll see that to run the tests, each launches the JUnit junit.textui.TestRunner class.

  1. In the command shell, browse to the StockWatcher directory.
  2. Run the JUnit test in hosted mode.
    At the command line, enter ./StockWatcherTest-hosted
  3. The test runs as Java bytecode in a JVM.
    The simpleTest executes without error.
    Time: 34.554
    
    OK (1 test)
  4. Run the JUnit test in web mode.
    At the command line, enter ./StockWatcherTest-web
  5. The test runs as compiled JavaScript.
    The simpleTest executes without error.
    Time: 30.065
    
    OK (1 test)

Running a compiled GWTTestCase subclass under JUnit launches an invisible instance of the Hosted Mode browser which emulates your application behavior during test execution.

In Eclipse

You can run unit tests in Eclipse. When you pass GWT junitCreator the optional -eclipse flag, it generates Eclipse launch configurations for both hosted mode and web mode.

  1. Run the JUnit test in hosted mode.
    From the Eclipse menu bar, select Run As > Open Run Dialog...
  2. In the Run window, select StockWatcherTest-hosted
  3. If you are using Mac OSX, add the argument to invoke the Java virtual machine.
    Display the Arguments tab.
    At VM argument, enter -XstartOnFirstThread -Xmx256M
    To save the changes to the Arguments, press Apply
    To run the test, press Run
  4. The simpleTest executes without error.
    screenshot: JUnit tests in Eclipse
  5. Run the JUnit test in web mode.
    From the Eclipse menu bar, select Run As > Open Run Dialog...
  6. In the Run window, select StockWatcherTest-web
  7. If you are using Mac OSX, add the argument to invoke the Java virtual machine.
    Display the Arguments tab.
    At VM argument, enter -XstartOnFirstThread -Xmx256M
    To save the changes to the Arguments, press Apply
    To run the test, press Run
  8. The simpleTest executes without error.

In manual test mode

If you want to select the browser on which to run unit tests, use manual test mode. In manual test mode, the JUnitShell main class runs as usual on a specified GWT module, but instead of running the test immediately, it prints out a URL and waits for a browser to connect. You can manually cut and paste this URL into the browser of your choice, and the unit tests will run in that browser.

In Depth: To learn how to run unit tests in manual mode, see the Developer's Guide, Creating a Test Case.

3. Writing a unit test

In a real testing scenario, you would want to verify the behavior of as much of StockWatcher as possible. You could add a number of unit tests to the StockWatcherTest class. You would write each test in the form of a public method.

If you had a large number of test cases, you could organize them by grouping them into different test classes, each generated by junitCreator.

However, to learn the process of setting up JUnit tests in GWT, in this tutorial you'll write just one test and run it.

  1. Write a JUnit test to verify that the constructor of the StockPrice class is correctly setting the new object's instance fields.
    To the StockWatcherTest class, add the testStockPriceCtor method as shown below.
    /**
     * Verify that the instance fields in the StockPrice class are set correctly.
     */
    public void testStockPriceCtor() {
      String symbol = "XYZ";
      double price = 70.0;
      double change = 2.0;
      double changePercent = 100.0 * change / price;
    
      StockPrice sp = new StockPrice(symbol, price, change);
      assertNotNull(sp);
      assertEquals(symbol, sp.getSymbol());
      assertEquals(price, sp.getPrice(), 0.001);
      assertEquals(change, sp.getChange(), 0.001);
      assertEquals(changePercent, sp.getChangePercent(), 0.001);
    }
  2. Rerun StockWatcherTest in hosted mode.
    Both tests should pass.
    Time: 30.065
    
    OK (2 tests)

4. Resolving problems identified in unit tests

To see what happens when a unit test fails, you'll reintroduce the arithmetic bug you fixed in the Getting Started tutorial. Originally, the percentage of change was not calculated correctly in the getChangePercent method. To make the unit test fail, you'll break this bit of code again.

  1. Introduce a bug into StockWatcher.
    In StockPrice.java, make the change highlighted below.
      public double getChangePercent() {
        return 10.0 * this.change / this.price;
      }
    
  2. Run StockWatcherTest in hosted mode (either in Eclipse of from the command line).
    JUnit identifies the failed test case (testStockPriceCtor).
    (Output if run in Eclipse.)
    screenshot: JUnit tests failed
    ...and provides a full-stack trace for the exception that resulted—an AssertionFailedError.
    (Output if run from the command line.)
    Time: 28.704
    There was 1 failure:
    1) testStockPriceCtor(com.google.gwt.sample.stockwatcher.client.StockWatcherTest)junit.framework.AssertionFailedError:
        expected=2.857142857142857 actual=0.2857142857142857 delta=0.0010
    
    ...
    
    FAILURES!!!
    Tests run: 2,  Failures: 1,  Errors: 0
  3. Correct the error.
  4. Rerun the tests.
    Both the JUnit tests should complete successfully again.
    Time: 34.123
    
    OK (2 tests)
    

Best Practices: Because there can be subtle differences between the way GWT applications work when compiled to JavaScript and when running as Java bytecode, make sure you run your unit tests in both hosted and web modes as you develop your application. Be aware, though, that if your test cases fail when running in web mode, you won't get the full stack trace that you see in hosted mode.

More about testing

At this point, you've created a JUnit test for StockWatcher and added a simple test case to it.

To learn more about all kinds of unit testing in GWT, see the Developer's Guide: