JUnit Recipe please

GWT Designer allows you to quickly create the modules, composites, panels, remote services and other elements that comprise Google Web Tookit applications.

Moderators: Konstantin.Scheglov, gnebling, Alexander.Mitin, jwren, Eric Clayberg

JUnit Recipe please

Postby Mal » Mon Nov 05, 2007 4:44 pm

GWT Designer provides excellent support for setting up GWT JUnit test cases.

However, I've tried to set up GWT JUnit testing and have seemed to get
very close, but not quite there.

The Diso Blog steps seem to be incomplete (http://thediscoblog.com/2007/04/28/3-st ... n-eclipse/)
and the GWT documentation (http://code.google.com/webtoolkit/docum ... ation.html)
doesn't cover Eclipse.

Setting up and running JUnit tests in non-GWT Eclipse projects is a cinch.

Rather than describe what I've tried, and the error messages, it may
be generally helpful if there were a step-by-step recipe in the
GWT Designer documentation on setting up a JUnit test or two.

Something simple, such as testing that a Button has been instantiated,
and that its text property is as expected.

I would be delighted to test drafts of the recipe to help fill in any gaps.

Mal.
Mal
 
Posts: 15
Joined: Mon Sep 24, 2007 2:33 pm
Location: Melbourne, Australia

Postby Konstantin.Scheglov » Tue Nov 06, 2007 9:11 pm

We will add support for launching GWT JUnit tests, in same way as we support now launching GWT applications.

For now, to run GWT tests in Eclipse you need is following steps:

1. create some GWT module for tests T (may be in same project as module to test S);

2. create test that extents GWTTestCase and uses some logic from S. It should has method getModuleName() that returns name of module T. It will also use some classes/logic from S, GWTDesigner will suggest you import S into T and does this using quick fix.

3. try to run your test (single or tests suite) using usual JUnit launch. It will fail because you need gwt-dev-windows.jar in classpath.

4. open created launch, on classpath page (note, in launch configuration, not for project) add gwt-dev-windows.jar and also "src" folders of your GWT project(s).

5. launch, now it will work.

6. Once you will go further, for example use several tests in single TestSuite, there is one trap. TestSuite is not part of GWT (in contrast to GWTTestCase), so you should more TestSuite outside of GWT module (GWT Designer still will able to run it).

Here is some code:

Code: Select all
package com.mycompany.test.client;

import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.mycompany.project.client.MyService;
import com.mycompany.project.client.MyServiceAsync;

public class MyTest extends GWTTestCase {
   public String getModuleName() {
      return "com.mycompany.test.ImageViewer";
   }
   public void test_1() throws Exception {
      MyServiceAsync service = MyService.Util.getInstance();
      service.getMessage("kosta", new AsyncCallback() {
         public void onSuccess(Object result) {
            System.out.println("onSuccess: " + result);
            finishTest();
         }
         public void onFailure(Throwable caught) {
            caught.printStackTrace();
            fail();
         }
      });
      delayTestFinish(1000);
   }
}


Hm... I've uploaded small project with test. Not ideal, but enough to understand I hope.

http://konstantin.scheglov.googlepages.com/GWTTest_junit.rar
Last edited by Konstantin.Scheglov on Tue Nov 20, 2007 3:30 am, edited 1 time in total.
Konstantin.Scheglov
Moderator
 
Posts: 186
Joined: Tue Oct 18, 2005 8:11 pm
Location: Russian Federation, Lipetsk

Postby Mal » Wed Nov 07, 2007 9:18 pm

Hi Konstantin,

Thanks for your reply.

I am trying to test only client side code in hosted mode, using Eclipse and Designer.
This seems to me to be the simplest first step, before
venturing into testing server-side communication.

So my example test class creates a button and does a couple of simple
JUnit assertions. I'll spell out what I do so you can see immediately
where I have gone wrong:

First of all, the EntryPoint classes is:

Code: Select all
package au.gov.bom.aifs.webcam.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class DesignerJUnit implements EntryPoint {
   private MyExtendedButton   clickMeButton;

   public void onModuleLoad() {
      RootPanel rootPanel = RootPanel.get();

      clickMeButton = new MyExtendedButton();
      rootPanel.add(clickMeButton);
      clickMeButton.setText("Click me!");
      clickMeButton.setMyButtonData("SOME BUTTON DATA");
      clickMeButton.addClickListener(new ClickListener() {
         public void onClick(Widget sender) {
            MyExtendedButton myButton = (MyExtendedButton)sender;
            Window.alert("Hello, GWT World!" + " and my data is: " + myButton.getMyButtonData());
         }
      });
   }
}

It uses an extension of the Button class:

Code: Select all
package au.gov.bom.aifs.webcam.client;

import com.google.gwt.user.client.ui.Button;

public class MyExtendedButton extends Button {

   private String   myButtonData;

   public MyExtendedButton() {
   }

   /**
    * @return the myButtonData
    */
   public String getMyButtonData() {
      return myButtonData;
   }

   /**
    * @param myButtonData
    *            the myButtonData to set
    */
   public void setMyButtonData(String myButtonData) {
      this.myButtonData = myButtonData;
   }
}

I created class MyExtendedButtonTest using the Eclipse New JUnit
Test Case menu option, and told it the Class under test is:
au.gov.bom.aifs.webcam.client.MyExtendedButton
and that its Superclass is:
GWTTestCase
I selected Test Methods for getMyButtonData() and the constructor.

I used Organize Imports to import the fully-qualified GWTTestCase class.

I used Quick Fix to add the unimplemented method getModuleName().
I modified getModuleName() to return the fully-qualified name of
the Module:
"au.gov.bom.aifs.webcam.client.DesignerJUnit"

I right-clicked in the Package Explorer on MyExtendedButtonTest.java
and invoked Run As | JUnit Test.

It failed, as we expected, with the GWTShell exception.

So far, so good.

The next step: Run | Open Run Dialogue | Classpath
Clicked on Bootstrap Entries
Clicked on Add External JARs and selected gwt-dev-windows.jar

Clicked on Apply then Run

java.lang.ExceptionInInitializerError
at com.google.gwt.junit.client.GWTTestCase.runTest(GWTTestCase.java:194)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:120)
at com.google.gwt.junit.client.GWTTestCase.run(GWTTestCase.java:114)
at junit.framework.TestSuite.runTest(TestSuite.java:230)
at junit.framework.TestSuite.run(TestSuite.java:225)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.lang.NullPointerException
at com.google.gwt.util.tools.Utility.computeInstallationPath(Utility.java:282)
at com.google.gwt.util.tools.Utility.getInstallPath(Utility.java:223)
at com.google.gwt.util.tools.ToolBase.<clinit>(ToolBase.java:55)
... 15 more

That's may be what you expected, given that I haven't added the "src"
folder yet.

Next: Run | Open Run Dialogue | Classpath
Clicked on Bootstrap Entries
Then clicked on Advanced | Add Folders
Selected the DesignerJunit project.

Apply and Run

It fails with the following stack trace in the Eclipse Console:

java.lang.NoClassDefFoundError: com/google/gwt/junit/client/GWTTestCase
at java.lang.ClassLoader.findBootstrapClass(Native Method)
at java.lang.ClassLoader.findBootstrapClass0(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClass(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClasses(RemoteTestRunner.java:425)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:445)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

The application compiles and runs correctly in hosted mode. There's no
problem there. It's getting JUnit working with GWT that's the problem.

Can you tell me where I have gone wrong, or what to do next?

Regards, Mal.
Australian Bureau of Meteorology
Mal
 
Posts: 15
Joined: Mon Sep 24, 2007 2:33 pm
Location: Melbourne, Australia

Postby Konstantin.Scheglov » Fri Nov 09, 2007 10:55 pm

com/google/gwt/junit/client/GWTTestCase is in gwt-user.jar

Probably your mistake is that you used bootstrap entries.

Look here Image how I configured classpath for JUnit.
Konstantin.Scheglov
Moderator
 
Posts: 186
Joined: Tue Oct 18, 2005 8:11 pm
Location: Russian Federation, Lipetsk

Postby Mal » Sun Nov 11, 2007 7:18 pm

Hi Konstantin,

Thanks for your help.


I fixed the method:
public String getModuleName() {
return "com.mycompany.project.ImageViewer";
}

It had been returning: "com.mycompany.project.client.ImageViewer"
I changed it to return: "com.mycompany.project.ImageViewer"

I didn't need to explicitly tell Eclipse where to look for the source.
The error message was:
Unable to find 'com/mycompany/project/ImageViewer.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?
And it went away as soon as I fixed the getModuleName() return value.


Here is my brief recipe for writing the smallest JUnit test of a GWT application:

(1) New GWT Java Project | DesignerJUnitHowTo

Accepted the default values such as package com.mycompany.project.client


(2) Created a method in ImageViewer to test

public static String getMyString() {
return "My String";
}


(3) New JUnit Test Case

Accepted default values such as Name: ImageViewerTest

Accepted (for now: will change later) default JUnit Superclass: junit.framework.TestCase

Message: JUnit 3 is not on the build path of project 'DesignerJUnitHowTo'. Click here to
add JUnit 3 to the build path and open the build path dialog.

Click: "Click here"
Click: Okay.

Click: Next
Tick: getMyString()
Click: Finish


(4) Modified ImageViewerTest.java to extend GWTTestCase

Used Quick Fix to import com.google.gwt.junit.client.GWTTestCase

Used Quick Fix to add unimplemented method: public String getModuleName()

Modified getModuleName() to return: "com.mycompany.project.ImageViewer"

Modify test method to implement the method body:
public void testGetMyString() {
assertEquals(ImageViewer.getMyString(), "My String");
}


(5) Right-click in Package Explorer on ImageViewerTest.java
Run As: JUnit Test

As expected, the test fails to run correctly. But Eclipse has now created a Run Configuration.

Click on Run | Open Run Dialog | Classpath

Click: User Entries
Click: Add External Jars
Browse to your GWT libraries
Select gwt-dev-windows.jar (if your on a Windows machine)

Apply
Run

Or:

Right-click in Package Explorer on ImageViewerTest.java
Run As: JUnit Test

Eclipse pops up its JUnit window and runs the test. :)

Regards, Mal.
Australian Bureau of Meteorology
Mal
 
Posts: 15
Joined: Mon Sep 24, 2007 2:33 pm
Location: Melbourne, Australia

Postby Eric Clayberg » Mon Nov 12, 2007 8:11 pm

Thank for your recipe. It sounds like you have it working nicely now.
Eric Clayberg
Software Engineering Manager
Google
http://code.google.com/webtoolkit/download.html

Author: "Eclipse Plug-ins"
http://www.qualityeclipse.com
Eric Clayberg
Moderator
 
Posts: 4503
Joined: Tue Sep 30, 2003 6:39 am
Location: Boston, MA USA

JUnit Recipe

Postby muks » Thu Nov 15, 2007 1:59 pm

Hi Konstantin,

Thanks. Your recipe works nicely.

However I need help to fit it into our development environment.

We have a GWT module, with multiple composites being developed by different developers. They all are part of the same module. Ideally I would like each of the developers to write their (GWT) JUnit test cases. I would like each of the Junit test cases (for each screen) to be in a separate source file, and part of the Test (T) module and they can be run by a JUnit Test suite.

This would enable us to avoid the contention for the single source file.

Is this feasible? I had trouble when I tried to have another Junit source within T. My T module has ImageViewer2Test.java extending GWTTestCase. I also added the source folder containing ImageViewer2Test.gwt.xml to classpath. It worked neat. I added additional source ImageViewer3Test also extending GWTTestCase.

While running I get the following error:
Finding entry point classes
[ERROR] Unable to find type 'com.mycompany.test.client.ImageViewer2Test'
[ERROR] Hint: Check that the type name 'com.mycompany.test.client.ImageViewer2Test' is really what you meant
[ERROR] Hint: Check that your classpath includes all required source roots

Any thoughts? Please let me know if you need me to explain in more detail.
muks
 
Posts: 3
Joined: Wed Nov 14, 2007 4:07 pm

Postby Konstantin.Scheglov » Thu Nov 15, 2007 9:34 pm

Note that couple days ago we've added support for running JUnit GWT tests using special launch configuration. You can even use "Run As..." context menu over your test. By using this you will avoid manual configuration of launch, so may be avoid problem.

Download latest continuous build and check if it helps you.
Konstantin.Scheglov
Moderator
 
Posts: 186
Joined: Tue Oct 18, 2005 8:11 pm
Location: Russian Federation, Lipetsk

Postby muks » Fri Nov 16, 2007 7:48 am

Works with newer GWTDesigner. Thanks
muks
 
Posts: 3
Joined: Wed Nov 14, 2007 4:07 pm

Postby Eric Clayberg » Sun Nov 18, 2007 6:33 pm

Here are the docs on the new JUnit GWT Application launch configuration.

Image

Image
Eric Clayberg
Software Engineering Manager
Google
http://code.google.com/webtoolkit/download.html

Author: "Eclipse Plug-ins"
http://www.qualityeclipse.com
Eric Clayberg
Moderator
 
Posts: 4503
Joined: Tue Sep 30, 2003 6:39 am
Location: Boston, MA USA


Return to GWT Designer

Who is online

Users browsing this forum: No registered users and 3 guests