Testing GWT code with Maven

One special aspect of gwt-maven-plugin to be familiar with is that it runs its own special test goal during the "test" phase in order to support GWTTestCase and GWTTestSuite derived GWT tests.

It's a long story as to why this is needed (having to do with classpath inspection and setup issues inside GWTTestCase/JUnitShell), but the regular Maven Surefire testing plugin does not work for GWTTestCase tests (at least not with any configuration we have tried, and we have given it a lot of efforts).

Using this special testing support though, requires that you know a few key things, as outlined below:

Invoking tests

The gwt-maven-plugin testing support is not intended to be run standalone, rather it is bound to the Maven "integration-test" phase. To get gwt:test to run, you should include the "test" goal in your plugin configuration executions, and you should invoke mvn test.

<project>
  [...]
  <build>
    <plugins>
      [...]
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>gwt-maven-plugin</artifactId>
        <version>1.1</version>
        <executions>
              <execution>
            <goals>
                  <goal>test</goal>
                </goals>
          </execution>
        </executions>
      </plugin>
      [...]
    </plugins>
  </build>
  [...]
</project>        

Separate GwtTest tests from standard unit tests

Because you will likely want to run both Surefire and gwt-maven-plugin based tests (for regular server side JUnit tests with Surefire, and for client model and controller tests with GWT) you need to distinguish these tests from each other. This is done using a naming convention.

You can configure the Surefire plugin (responsible for running tests during maven build) to skip the GwtTests using some naming patterns :

      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.4.3</version>
        <configuration>
          <excludes>
            <exclude>**/*GwtTest.java</exclude>
          </excludes>
        </configuration>
      </plugin>

A simplier way to separate classic and GWT tests is to name latests GwtTest"Something.java - they start with "GwtTest". Surefire looks for tests that are named Something"Test".java by default - they end with "Test".

By default, the gwt-maven-plugin uses GwtTest*.java as inclusion pattern so that GwtTest will not match the standard Surefire pattern. Using this convention you don't have to change your configuration.

To configure the plugin to use such a naming convention, set the includes plugin parameter.

        <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>gwt-maven-plugin</artifactId>
                <version>1.1</version>
                <configuration>
                  <includes>**/CustomPattern*.java</includes>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                </executions>
        </plugin>

Test results output

The plugin mimics as far as possible standard Surefire execution and contributes to execution report. If you use the surefire-report-plugin, you will see the GwtTests result included in generated project site.

Use GWTTestSuite padawan

GWTTestCase derived tests are slow. This is because the JUnitShell has to load the module for each test (create the shell, hook into it, etc). http://google-web-toolkit.googlecode.com/svn/javadoc/1.5/com/google/gwt/junit/tools/GWTTestSuite.html}GWTTestSuite mitigates this by grouping all the tests that are for the same module (those that return the same value for getModuleName) together and running them via the same shell instance.

This is a big time saver, and GWTTestSuite is easy to use, so using it is a good idea. For this reason, the default value of the test inclusion pattern is **/Gwt*Suite.java.

We recommend to name your test suite GwtTestSuite.java so that the test filter picks it up, but name the actual tests with a convention that Surefire will ignore by default - something that does not start with GwtTest, and does not start or end with Test. For example MyClassTestGwt.java. This way, gwt-maven-plugin picks up the Suite, and runs it, but does not also run individual tests (and Surefire does not pick it up either)

Run GWTTestCase during "test" phase

We do not consider GWTTestCase to be unit test as they require the whole GWT Module to run. For this reason, the test goal is bound by default to integration-test phase. But this is only our point of view and you may want to run such test during the standard test phase. To do this, you just need to define a dedicated execution and to override the default phase

<project>
  [...]
  <build>
    <plugins>
      [...]
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>gwt-maven-plugin</artifactId>
        <version>1.1</version>
        <executions>
              <execution>
                <id>test</id>
            <goals>
                  <goal>test</goal>
                </goals>
                <phase>test</phase>
          </execution>
        </executions>
      </plugin>
      [...]
    </plugins>
  </build>
  [...]
</project>