Introduction to GWT JUnit test

488 views
Skip to first unread message

Gohan

unread,
Feb 1, 2007, 2:27:23 AM2/1/07
to Google Web Toolkit
Hi,

I've heard much about the ability to test (especially with JUnit) your
code in GWT, in both hosted mode and web mode. Though I've not seen
any real examples of how to go about. Can anyone point me in the
direction to where I can find a good JUnit test for a GWT widget? And
is it even possible to unit test widgets thoroughly? There's no sence
of inversion of control out of the box and there seem to be some
static methods as well (RootPanel for exampleI) so it's difficult to
get much help from e.g. EasyMock. Or is it unit testing in this sence
intended to be used only on "non widget" methods (i.e. methods where
there is no widget logic) where you have some other logic that's
testable? Mabey I've got it all wrong here because I can't see why the
"invisible" GWT browser need to run if you extend GWTTestCase in your
unit tests? But I figure tests extending GWTTestCase are intended to
be integration unit tests and not real unit tests. But anyway, I'd
really like to see an example on how you should write a JUnit test for
GWT.

Thanks,
Johan

brunopedroso

unread,
Feb 28, 2007, 8:30:38 PM2/28/07
to Google Web Toolkit
I'm trying to write some tests too, and I'm not understanding it
either...

I could write a test that made some successfull RPC calls, but when I
call button.click(), the ClickListener is not called...

Can GWT realy be unit tested ?

On 1 fev, 04:27, "Gohan" <hal...@gmail.com> wrote:
> Hi,
>

> I've heard much about the ability to test (especially withJUnit) your


> code in GWT, in both hosted mode and web mode. Though I've not seen
> any real examples of how to go about. Can anyone point me in the

> direction to where I can find a goodJUnittest for a GWT widget? And

charlie...@gmail.com

unread,
Feb 28, 2007, 9:55:09 PM2/28/07
to Google Web Toolkit
You cannot test UI with GWTTestCase (at least not under any normal
path, that is not really what it is for).

The reason for GWTTestCase, which invokes the GWT JUnitShell, is so
that you can test your GWT model components and any client side
controller logic, and the RPC transition, and such - not UI. The
JUnitShell involves the GWT compiler and allows "Hosted" mode and
"Web" mode tests. Without this you could not test GWT stuff.

So the answer to "can GWT really be unit tested" is yes. But not the
way you might expect, not to the UI. If you are writing RPC tests,
then you are testing half of what GWT testing is all about. The other
half is client side non UI code, client side logic, a client side
controller for example (when a method is called on the controller,
which ends up updating the model after a service call, does that model
update its listeners).

That may sound strange, because a large part of the toolkit is UI
focused, but once you are doing event handling and maintaining a
client side model and using GWT RPC (the "canonical" GWT app) the only
thing the UI really does is fire the events to your controller/model -
which you can do without UI in tests. (And at that point if you could
test UI, you would only be testing whether or not the button click
fires the ClickListener, which is actually not a very important
"test".)

Here is an example of a test that includes a GWT serializable "Person"
object and an RPC call - this is really where GWT tests come in handy,
not in testing ClickListener. This test exercises a client side
controller, a serialized type, a client side model and RPC.


package com.manning.gwtip.testme.client;

import junit.framework.Assert;

import com.google.gwt.junit.client.GWTTestCase;
import com.manning.gwtip.testme.client.controller.Controller;
import com.manning.gwtip.testme.client.model.ModelData;
import com.manning.gwtip.testme.client.model.ModelListener;
import com.manning.gwtip.testme.client.model.PeopleModelData;
import com.manning.gwtip.testme.client.model.Person;


/**
* GWT JUnit tests must extend GWTTestCase.
*/
public class MyServiceGwtTest extends GWTTestCase {


// Play around with the timing to make the tests timeout and fail.
// This tests your code AND checks up on the GWT delayTestFinish
logic.
//
// Using 20 for TEST_DELAY_1 for example, you should be able to
get GWTTestCase to throw a TimeoutException in test 1.
// Using 3020 for TEST_DELAY_2 for example, you should be able to
get GWTTestCase to throw a TimeoutException in test 2.
(addorUpdatePerson2 is identical to addOrUpdatePerson1 except it
contains a Thread.sleep on the server side to slow down the RPC for
this text example - sleep(3000))
private static final int TEST_DELAY_1 = 50;
private static final int TEST_DELAY_2 = 3050;

public String getModuleName() {
return "com.manning.gwtip.testme.TestMe";
}

public void setUp() throws Exception {
super.setUp();
}

public void tearDown() throws Exception {
super.tearDown();
}

public void testAddOrUpdatePerson1() {
Person person = new Person("Angus", "Young");

PeopleModelData peopleData = new PeopleModelData();
Controller controller = new Controller(peopleData);

peopleData.addListener(new ModelListener() {
public void onChange(ModelData data) {
PeopleModelData pd = (PeopleModelData) data;
Assert.assertEquals(1, pd.getPeople().size());
finishTest();
}
});

delayTestFinish(TEST_DELAY_1);
controller.addOrUpdatePerson(person);
}

public void testAddOrUpdatePerson2() {
Person person = new Person("Bon", "Scott");

PeopleModelData peopleData = new PeopleModelData();
Controller controller = new Controller(peopleData);

peopleData.addListener(new ModelListener() {
public void onChange(ModelData data) {
PeopleModelData pd = (PeopleModelData) data;
Assert.assertEquals(2, pd.getPeople().size());
finishTest();
}
});

delayTestFinish(TEST_DELAY_2);
controller.addOrUpdatePersonSlow(person);

brunopedroso

unread,
Mar 2, 2007, 6:56:40 PM3/2/07
to Google Web Toolkit
Great! Thanks for the answer! It's exactly what I wanted to
understand... What is GWTTestCase about. It is not writen in the docs.
(I couldn't found it...)
Thanks very much!


On 28 fev, 23:55, "charlie.coll...@gmail.com"


<charlie.coll...@gmail.com> wrote:
> You cannot test UI with GWTTestCase (at least not under any normal
> path, that is not really what it is for).
>
> The reason for GWTTestCase, which invokes the GWT JUnitShell, is so
> that you can test your GWT model components and any client side
> controller logic, and the RPC transition, and such - not UI. The
> JUnitShell involves the GWT compiler and allows "Hosted" mode and
> "Web" mode tests. Without this you could not test GWT stuff.
>
> So the answer to "can GWT really be unit tested" is yes. But not the
> way you might expect, not to the UI. If you are writing RPC tests,
> then you are testing half of what GWT testing is all about. The other
> half is client side non UI code, client side logic, a client side

> controller forexample(when a method is called on the controller,


> which ends up updating the model after a service call, does that model
> update its listeners).
>
> That may sound strange, because a large part of the toolkit is UI
> focused, but once you are doing event handling and maintaining a
> client side model and using GWT RPC (the "canonical" GWT app) the only
> thing the UI really does is fire the events to your controller/model -
> which you can do without UI in tests. (And at that point if you could
> test UI, you would only be testing whether or not the button click
> fires the ClickListener, which is actually not a very important
> "test".)
>

> Here is anexampleof a test that includes a GWT serializable "Person"


> object and an RPC call - this is really where GWT tests come in handy,
> not in testing ClickListener. This test exercises a client side
> controller, a serialized type, a client side model and RPC.
>
> package com.manning.gwtip.testme.client;
>
> importjunit.framework.Assert;
>
> import com.google.gwt.junit.client.GWTTestCase;
> import com.manning.gwtip.testme.client.controller.Controller;
> import com.manning.gwtip.testme.client.model.ModelData;
> import com.manning.gwtip.testme.client.model.ModelListener;
> import com.manning.gwtip.testme.client.model.PeopleModelData;
> import com.manning.gwtip.testme.client.model.Person;
>
> /**

> * GWTJUnittests must extend GWTTestCase.


> */
> public class MyServiceGwtTest extends GWTTestCase {
>
> // Play around with the timing to make the tests timeout and fail.
> // This tests your code AND checks up on the GWT delayTestFinish
> logic.
> //

> // Using 20 for TEST_DELAY_1 forexample, you should be able to


> get GWTTestCase to throw a TimeoutException in test 1.

> // Using 3020 for TEST_DELAY_2 forexample, you should be able to


> get GWTTestCase to throw a TimeoutException in test 2.
> (addorUpdatePerson2 is identical to addOrUpdatePerson1 except it
> contains a Thread.sleep on the server side to slow down the RPC for

> this textexample- sleep(3000))

Reply all
Reply to author
Forward
0 new messages