Does GWTTestCase still work?

193 views
Skip to first unread message

Craig Mitchell

unread,
Apr 27, 2025, 12:54:36 AMApr 27
to GWT Users
I created a demo project with https://github.com/NaluKit/gwt-maven-springboot-archetype with the params:
- modular-springboot-webapp
- groupId: test.craig
- artifactId: testing
- module-short-name app: tc

Added JUnit to the client pom:
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.13.2</version>
  <scope>test</scope>
</dependency>

Created a simple test in the client module (in src/test/java/test/craig/MyTests.java):
public class MyTests extends GWTTestCase {
  @Override
  public String getModuleName() {
    return "test.craig.App";
  }
  public void testSimple() {
    assertTrue( true );
  }
}

Tried to run it in IntelliJ, but got the error:
com.google.gwt.junit.JUnitFatalLaunchException: The test class 'test.craig.MyTests' was not found in module 'test.craig.App'; no compilation unit for that type was seen

Tried to compile and run it from the command line:
java junit.textui.TestRunner test.craig.MyTests

But that returned:
Error: Could not find or load main class junit.textui.TestRunner
Caused by: java.lang.ClassNotFoundException: junit.textui.TestRunner

I thought I was following the instructions in https://www.gwtproject.org/doc/latest/DevGuideTesting.html but obviously doing something wrong.

Any help is much appreciated.

Craig Mitchell

unread,
Apr 27, 2025, 1:18:17 AMApr 27
to GWT Users
When running from the command line, I forgot to add all the items to the class path.  Once I did that, I got the same error IntelliJ did:

There was 1 error:
1) testSimple(test.craig.MyTests)com.google.gwt.junit.JUnitFatalLaunchException: The test class 'test.craig.MyTests' was not found in module 'test.craig.App'; no compilation unit for that type was seen
        at com.google.gwt.junit.JUnitShell.checkTestClassInCurrentModule(JUnitShell.java:741)
        at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java:1360)
        at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java:1316)
        at com.google.gwt.junit.JUnitShell.runTest(JUnitShell.java:679)
        at com.google.gwt.junit.client.GWTTestCase.runTest(GWTTestCase.java:421)
        at com.google.gwt.junit.client.GWTTestCase.run(GWTTestCase.java:247)

FAILURES!!!
Tests run: 1,  Failures: 0,  Errors: 1

Thomas Broyer

unread,
Apr 27, 2025, 8:26:04 AMApr 27
to GWT Users
What does your test/craig/App.gwt.xml look like? Does its <source> include MyTests.java?

Colin Alworth

unread,
Apr 27, 2025, 8:30:10 AMApr 27
to GWT Users
When using maven, running from the command line should be "mvn test". With the plugin you are using, it is assumed you are using a test suite - this is not required, but scales better. If you only need to run a single test, you can modify this includes.


For example in your project with MyTests (note: that wouldn't run even in a non-gwt project from maven, the default pattern is *Test), you could add this:
          <includes>
            <include>test/craig/MyTests.java</include>
          </includes>

When I do that, having built the sample as you describe, the tests passes with mvn test:
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running test.craig.MyTests
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 13.96 s -- in test.craig.MyTests
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

When running from IJ, it doesnt automatically add sources to the classpath as gwt:test does, so you may just want to call the maven goal directly instead. I recall that it is possible to configure Maven/IJ to run tests "normally", but can't quickly spot what that would be.

Craig Mitchell

unread,
Apr 27, 2025, 7:26:13 PMApr 27
to GWT Users
Thanks Colin.  I wasn't aware of the "Suite" naming convention.

So, to summarise.  Either:
- Put "Suite" or "SuiteNoBrowser" at the end of the test class name, or
- Add the test class directly as an include in the client pom.xml, in the gwt-maven-plugin.

Now working great!

Craig Mitchell

unread,
May 9, 2025, 10:01:52 PMMay 9
to GWT Users
In the GWTTestCase client tests, if I want to test code that's in the shared module.  Eg:

assertTrue( FieldVerifier.isValidName("hi") );

I get the error:
[ERROR] Line 13: No source code is available for type test.craig.FieldVerifier; did you forget to inherit a required module?

How can I inherit the shared module for the GWTTestCase tests?

Craig Mitchell

unread,
May 10, 2025, 2:51:35 AMMay 10
to GWT Users
Some extra (strange) behaviours:

Creating a class in the client module:
public class FieldVerifierOverride extends FieldVerifier { }

And then calling the test with this class:
assertTrue( FieldVerifierOverride.isValidName("hi") );

Gives a different error:
[ERROR] Could not find test.craig.FieldVerifier in types compiled from source. Is the source glob too strict?

Also, if I run mvn package (instead of mvn test), then the test actally runs, but FieldVerifier.isValidName("hi") returns false (it should return true):
  [ERROR] test.craig.MyTests.testSimple -- Time elapsed: 8.016 s <<< FAILURE!
  junit.framework.AssertionFailedError: expected: <true>, actual: <false>

Craig Mitchell

unread,
May 10, 2025, 2:58:07 AMMay 10
to GWT Users
Apologies.  Doing a mvn package does work.  The tests run successfully.  Doing a mvn test does not work (gives the "No source code is available for type test.craig.FieldVerifier; did you forget to inherit a required module?"" error).

Craig Mitchell

unread,
May 10, 2025, 3:24:37 AMMay 10
to GWT Users
(Sorry for the spamming)  Now I am able to run my tests, I see they are rather slow, and they timeout with the message "Try increasing this timeout using the '-testMethodTimeout minutes' option".

I'm running in Maven and trying to add this argument.  I've tried putting it in the POM:
<gwt.testMethodTimeout>10</gwt.testMethodTimeout>

Also via the command line:
mvn package "-DtestMethodTimeout=10"
mvn package "-DtestMethodTimeout 10"

It just keeps using the default of 5 minutes.  Any idea how to set the timeout?

Craig Mitchell

unread,
May 11, 2025, 12:29:29 AMMay 11
to GWT Users
If it helps, this is where it's setting the default timeout of 5 minutes:  https://github.com/gwtproject/gwt/blob/main/user/src/com/google/gwt/junit/JUnitShell.java#L318  I'm just stuck on how to override it.

Also, if I run  mvn clean install gwt:test -pl *-client  that seems to run the tests (but it's easier to type mvn package 🙂)

Thomas Broyer

unread,
May 12, 2025, 3:41:37 AMMay 12
to GWT Users
Use the gwt.args system property to pass arguments to GWT's JUnitShell: https://www.gwtproject.org/doc/latest/DevGuideTesting.html#passingTestArgumentshttps://maven.apache.org/surefire/maven-surefire-plugin/examples/system-properties.html
<systemPropertyVariables>
  <gwt.args>-testMethodTimeout 10</gwt.args>
</systemPropertyVariables>

But with my maven plugin, you can also "just" use <testArgs> in the plugin configuration: https://tbroyer.github.io/gwt-maven-plugin/test-mojo.html#testArgs
<testArgs>
  <arg>-testMethodTimeout</arg><arg>10</arg>
</testArgs>

Craig Mitchell

unread,
May 12, 2025, 9:32:52 AMMay 12
to GWT Users
Thank you Thomas!  The testArgs config worked perfectly.

Radek

unread,
May 18, 2025, 7:15:30 PMMay 18
to GWT Users
Hi,

Could you confirm that GWTTestCase only works if you’re still using the old javax.servlet API? It no longer works once you’ve migrated to Jakarta (e.g. Tomcat 10), right?

Regards,
Radek

Craig Mitchell

unread,
May 18, 2025, 7:34:31 PMMay 18
to GWT Users
I'm using gwt-servlet-jakarta and GWTTestCase worked fine.  I don't think GWTTestCase has anything to do with which web server you use.

It does use JUnit 4 though.  It won't work with JUnit 5.

Radek

unread,
May 19, 2025, 2:47:02 PMMay 19
to GWT Users
Thank you for the reply - although I’m still a bit confused. You’re running GWTTestCase on an embedded server, right? As far as I understand, JUnitShell.java:1123 calls asSubclass(javax.servlet.Servlet.class), so it shouldn’t work with the Jakarta servlet API - https://github.com/gwtproject/gwt/blob/main/user/src/com/google/gwt/junit/JUnitShell.java#L1123. Are you starting Jetty (or another servlet container) yourself in your tests so that GWT servlets run there? Or are you not actually send GWT RPC in your GWTTestCase?

Regards,
Radek

Craig Mitchell

unread,
May 19, 2025, 8:25:12 PMMay 19
to GWT Users
I think GWTTestCase uses HtmlUnit ( https://htmlunit.sourceforge.io/ ), so it doesn't need an embedded server running.

Having said that, it looks like something still brings in the old javax.servlet-api, so GWTTestCase can still use it.  But my webserver still uses the new jakarta.servlet-api:

Screenshot 2025-05-20 102243.png

Craig Mitchell

unread,
May 19, 2025, 8:36:29 PMMay 19
to GWT Users
Dependency: GWTTestCase brings in net.sourceforge.htmlunit which brings in javax.servlet-api.

Colin Alworth

unread,
May 19, 2025, 9:23:23 PMMay 19
to GWT Users
If you're writing unit tests, you almost certainly don't care about javax vs jakarta servlets.

If you're writing _integration_ tests, you might be putting <servlet> tags in the .gwt.xml, which will tie you to the same server implementation that the test tooling itself is using to communicate with the server. This is probably not a good idea, and there's no nice way planned to handle this (plus, it also means your server doesn't do much, except run inside the GWT JUnit server), since we either break everyone using javax and make them use jakarta, or we make them stick on jakarta forever. I don't see this in the wild very often, so this probably isn't what you're doing. This is the only case where you will be limited to javax.servlet.

If you're writing integration tests and running your own server at the same time as the test (e.g. some earlier task/goal to start jetty/tomcat/etc, then run the GWT tests, then shut down the server), you are not tied to what GWT uses internally - same as if you are running dev mode or code server with your own server running.

In terms of dependencies, gwt-dev.jar depends on javax.servlet both to run the SDM server and also to run HtmlUnit (which still supports Java 8 with no plans to drop this). You also don't want to mix gwt-dev.jar into your server classpath, there are a number of exciting ways that can go wrong.

Radek

unread,
May 20, 2025, 2:03:04 PMMay 20
to GWT Users
Thank you all for your insights! Yes, I was referring specifically to those GWT integration tests that rely on <servlet> entries in the .gwt.xml. It’s a shame they won’t work under Jakarta, but it’s really not a big deal - this is just a small hobby project, and I only had a single widget integration test with RemoteServiceServlet. I won’t miss it too much. All of my other tests invoke RemoteServiceServlet methods directly (without GWTTestCase, without widgets), so they remain completely unaffected after moving to Jakarta.

Thanks again for all your help!

Regards,
Radek
Reply all
Reply to author
Forward
0 new messages